The previous example covered the key features of how sockets get connected, but was dangerously simple. We sent a very short string, then waited a couple of seconds while we typed the call to receive a response. We got back the expected data, but were lucky: in real life, there’s more to worry about.
send() call doesn’t instantly send a
string, however long. It tries to send the string and returns the
number of bytes sent. With a big string (e.g., a file-transfer
application) or in bad network conditions, the
send() call sends only a small part on each call.
It might also return zero, which indicates that the network
connection has been broken. The only safe way to send a string is to
do it in a loop and check the return values to see what has actually
been sent. Here’s a function to send an arbitrary string
# this sends strings over sockets more safely def safeSend(sock, message): msglen = len(message) totalsent = 0 while totalsent < msglen: sent = sock.send(msg[totalsent:]) if sent == 0: raise RuntimeError, 'connection broken' totalsent = totalsent + sent
At this point you’ve hit a fundamental problem. There is no way for the receiving socket to know how much data to expect, nor whether a message has finished arriving. You have to design your protocol so that client and handler know what to expect at every stage. There are several schemes for doing this:
Always use fixed-size messages.
Add a final delimiter.
Indicate how long messages are. ...