diff --git a/Doc/howto/sockets.rst b/Doc/howto/sockets.rst index cbc49d15a0771b9..fa8f602f759fde4 100644 --- a/Doc/howto/sockets.rst +++ b/Doc/howto/sockets.rst @@ -167,15 +167,16 @@ request, then reads a reply. That's it. The socket is discarded. This means tha a client can detect the end of the reply by receiving 0 bytes. But if you plan to reuse your socket for further transfers, you need to realize -that *there is no* :abbr:`EOT (End of Transfer)` *on a socket.* I repeat: if a socket -``send`` or ``recv`` returns after handling 0 bytes, the connection has been -broken. If the connection has *not* been broken, you may wait on a ``recv`` -forever, because the socket will *not* tell you that there's nothing more to -read (for now). Now if you think about that a bit, you'll come to realize a -fundamental truth of sockets: *messages must either be fixed length* (yuck), *or -be delimited* (shrug), *or indicate how long they are* (much better), *or end by -shutting down the connection*. The choice is entirely yours, (but some ways are -righter than others). +that *there is no* :abbr:`EOT (End of Transfer)` *on a socket.* If a ``recv`` +returns 0 bytes, the connection has been broken. In contrast, you should never +call ``send`` on a broken socket: rather than returning 0, it will normally +raise an :exc:`OSError`. If the connection has *not* been broken, you may +wait on a ``recv`` forever, because the socket will *not* tell you that there's +nothing more to read (for now). Now if you think about that a bit, you'll come +to realize a fundamental truth of sockets: *messages must either be fixed +length* (yuck), *or be delimited* (shrug), *or indicate how long they are* +(much better), *or end by shutting down the connection*. The choice is entirely +yours, (but some ways are righter than others). Assuming you don't want to end the connection, the simplest solution is a fixed length message:: @@ -200,6 +201,9 @@ length message:: while totalsent < MSGLEN: sent = self.sock.send(msg[totalsent:]) if sent == 0: + # A broken connection almost always raises OSError + # from send(); a 0 return is rare, but guard against + # looping forever if it happens. raise RuntimeError("socket connection broken") totalsent = totalsent + sent