socket examples
Bryan Olson
fakeaddress at nowhere.org
Tue Jan 24 13:52:37 EST 2006
le dahut wrote:
> I have a server that receives data from a client, detect the end of this
> data and send other data back to the client (it's to measure bandwidth).
> I think the best way is to thread a part of the server's program am I
> right ?
Others disagree on this, but in most cases, yes: threads
are the way to go. Usually daemon threads. Start with:
import threading
Write a function to handle one connection.
def handler(conn, addr):
pass # move the per-connection code here
> HOST = socket.gethostname()
In most cases, you don't want that. In building the argument
to bind(), use socket.INADDR_ANY to accept connections on any
available interface, including the local loopback address.
The bind() function in Python's socket module will treat the
empty string as INADDR_ANY.
> try:
> PORT = int(sys.argv[1])
> print PORT
> except:
> PORT = 50009
> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
> print "s.bind((", HOST, PORT, "))"
> s.bind((HOST, PORT))
> s.listen(5)
> while 1:
> conn, addr = s.accept()
This is where you call your connection handling function.
t = threading.Thread(target=handler, args=(conn, addr))
t.setDaemon(True)
t.start()
Obviously, move the per-connection code into the handler()
function.
You might want to launch the thread within a try-except block,
with a catch-all except that logs an otherwise uncaught
exception.
> print 'Connected by', addr
> data=''
> while 1:
> data += conn.recv(1024)
Don't count on recv() returning more than one byte, even
from an open and healthy connection. See the doc for
socket.recv.
> if data[-5:] == '#####': #the end of the data
> break
There's a better way to shut down: when done sending data,
call socket.shutdown(socket.SHUT_WR). If the remote side
has shutdown writing, recv() will return the empty string
(after returning all the data, of course).
End-of-connection is the only case in which recv(nonzero)
will return the empty string. Also note that a socket will
select() as readable on end of connection.
Unfortunately, in some cases a connection that ends
because of an error can mimic graceful shutdown. A
zero-byte return from recv(nonzero) always means
end-of-data, but does not necessarily mean you've
received everything the remote side wanted to send.
>
> data2='1'*1024*1024
> data2=data2[:-5]+'#####' #the end of the data
> conn.send(data2)
Don't count on send() sending all the data you pass.
Python's sockets offer the convenient method sendall()
which does send all the data it is passed before returning.
When using a thread per connection, sendall() is the way
to go.
> conn.close()
Right; closing is good practice. As noted above, I
recommend shutting down writing and detecting end-of-data
before closing. Incidentally, shutting down reading is
utter trivia and best left to close().
--
--Bryan
More information about the Python-list
mailing list