The python3 socket programming howto presents this code snippet
class MySocket:
"""demonstration class only
- coded for clarity, not efficiency
"""
def __init__(self, sock=None):
if sock is None:
self.sock = socket.socket(
socket.AF_INET, socket.SOCK_STREAM)
else:
self.sock = sock
def connect(self, host, port):
self.sock.connect((host, port))
def mysend(self, msg):
totalsent = 0
while totalsent < MSGLEN:
sent = self.sock.send(msg[totalsent:])
if sent == 0:
raise RuntimeError("socket connection broken")
totalsent = totalsent + sent
def myreceive(self):
chunks = []
bytes_recd = 0
while bytes_recd < MSGLEN:
chunk = self.sock.recv(min(MSGLEN - bytes_recd, 2048))
if chunk == b'':
raise RuntimeError("socket connection broken")
chunks.append(chunk)
bytes_recd = bytes_recd + len(chunk)
return b''.join(chunks)
where the send loop is interrupted if the socket send method returns 0.
The logic behind this snippet is that when the send method returns '0 bytes sent', the sending side of a socket connection should give up its efforts to send data. This is for sure true for the recv method, where zero bytes read for a socket in blocking mode should be interpreted as EOF, and therefore the reading side should give up.
However I cannot understand under which situations the send method could return zero. My understanding of python sockets is that send returns immediately due to buffering at the OS level. If the buffer is full send will block, or if the connections is closed at the remote side, an exception is raised.
Finally suppose send returns zero without raising an exception: does this really indicate that all future send calls will return zero?
I've done some testing (although using only socket connected to ::1 on OS X) and was not able to find a situation in which send returns 0.
Edit
The HOWTO states:
But if you plan to reuse your socket for further transfers, you need to realize that there is no EOT 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).
It is pretty easy to find a situation in which recv returns 0: when the remote (sending) side calls socket.shutdown(SHUT_WR), further recv on the receiving side will return 0 and not raise any exception.
I'm looking for a concrete example where you can show that receiving 0 zero from send indicates a broken connection (which will continue to return 0 on send.)