Skip to content

Commit 235fdaa

Browse files
committed
gh-109532: keep zero-length guard, soften OSError claim
1 parent c0bb4bc commit 235fdaa

1 file changed

Lines changed: 12 additions & 9 deletions

File tree

Doc/howto/sockets.rst

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -169,13 +169,13 @@ a client can detect the end of the reply by receiving 0 bytes.
169169
But if you plan to reuse your socket for further transfers, you need to realize
170170
that *there is no* :abbr:`EOT (End of Transfer)` *on a socket.* If a ``recv``
171171
returns 0 bytes, the connection has been broken. In contrast, you should never
172-
call ``send`` on a broken socket, as it will raise an :exc:`OSError` rather than
173-
returning 0. If the connection has *not* been broken, you may wait on a
174-
``recv`` forever, because the socket will *not* tell you that there's nothing
175-
more to read (for now). Now if you think about that a bit, you'll come to
176-
realize a fundamental truth of sockets: *messages must either be fixed length*
177-
(yuck), *or be delimited* (shrug), *or indicate how long they are* (much
178-
better), *or end by shutting down the connection*. The choice is entirely
172+
call ``send`` on a broken socket: rather than returning 0, it will normally
173+
raise an :exc:`OSError`. If the connection has *not* been broken, you may
174+
wait on a ``recv`` forever, because the socket will *not* tell you that there's
175+
nothing more to read (for now). Now if you think about that a bit, you'll come
176+
to realize a fundamental truth of sockets: *messages must either be fixed
177+
length* (yuck), *or be delimited* (shrug), *or indicate how long they are*
178+
(much better), *or end by shutting down the connection*. The choice is entirely
179179
yours, (but some ways are righter than others).
180180

181181
Assuming you don't want to end the connection, the simplest solution is a fixed
@@ -199,9 +199,12 @@ length message::
199199
def mysend(self, msg):
200200
totalsent = 0
201201
while totalsent < MSGLEN:
202-
# No need to check for 0 here: send() raises OSError
203-
# if the connection is broken.
204202
sent = self.sock.send(msg[totalsent:])
203+
if sent == 0:
204+
# A broken connection almost always raises OSError
205+
# from send(); a 0 return is rare, but guard against
206+
# looping forever if it happens.
207+
raise RuntimeError("socket connection broken")
205208
totalsent = totalsent + sent
206209

207210
def myreceive(self):

0 commit comments

Comments
 (0)