If I close a server socket while in a s.recv_into()
loop from a client, I keep getting 0 from recv_into()
infinitely.
As I understand, the only way to know a socket is closed was not through the Python socket mechanism itself, but using select / poll / etc.
What's the rational of not returning -1 when the socket is closed by the other side? Why can't I properly differentiate "no data currently" from "no one there anymore"?
EDIT:
Perhaps the correct question is - why is no exception thrown when using recv()
, if the other side terminated the connection?
The recv_into
is just a wrapper of the C system call by name recv
. The return value of 0
is not an erroneous condition!
From Linux manuals, recv(2)
:
RETURN VALUE
These calls return the number of bytes received, or -1 if an error occurred. In the event of an error, errno is set to indicate the error.
When a stream socket peer has performed an orderly shutdown, the return value will be 0 (the traditional "end-of-file" return).
Datagram sockets in various domains (e.g., the UNIX and Internet domains) permit zero-length datagrams. When such a datagram is received, the return value is 0.
The value 0 may also be returned if the requested number of bytes to receive from a stream socket was 0.
For error cases, Python will not return -1
, instead it will raise an appropriate exception.
For a stream sockets you must break the loop whenever recv_*
returns a value that indicates that 0 bytes were received. There is no point for checking -1
, but in case you do want to be extra certain, you can naturally use while sock.recv_into(....) > 0:
or similar.
The various read
calls in Python work in similar fashion.