Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions Doc/howto/sockets.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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::
Expand All @@ -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

Expand Down
Loading