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