From test, I concluded that in following three cases the socket.recv(recv_size)
will return.
After the connection was closed. For example, the client side called socket.close() or any socket error occurred, it would return empty string.
Some data come, the size of data is more than recv_size
.
recv_size
and no more data come after a short time (I found 0.1s would work).More details about #3:
#server.py while True: data = sock.recv(10) print data, 'EOF' #client1.py sock.sendall("12345") sock.sendall("a" * 50) #client2.py sock.sendall("12345") time.sleep(0.1) sock.sendall("a" * 50)
When I run client1.py
, the server.py
echos:
12345aaaaa EOF aaaaaaaaaa EOF aaaaaaaaaa EOF aaaaaaaaaa EOF aaaaaaaaaa EOF aaaaa EOF
When I run client2.py
, the server.py
echos:
12345 EOF aaaaaaaaaa EOF aaaaaaaaaa EOF aaaaaaaaaa EOF aaaaaaaaaa EOF aaaaaaaaaa EOF
Are my conclusions correct? Where can I see the official description about #3?
The recv() call applies only to connected sockets. This call returns the length of the incoming message or data.
If no error occurs, recv returns the bytes received. If the connection has been gracefully closed, the return value is an empty byte string.
The recv function is used to read incoming data on connection-oriented sockets, or connectionless sockets. When using a connection-oriented protocol, the sockets must be connected before calling recv. When using a connectionless protocol, the sockets must be bound before calling recv.
If no messages are available at the socket, the recv() call waits for a message to arrive unless the socket is nonblocking. If a socket is nonblocking, -1 is returned and the external variable errno is set to EWOULDBLOCK.
Yes, your conclusion is correct. socket.recv
is a blocking call.
socket.recv(1024)
will read at most 1024 bytes, blocking if no data is waiting to be read. If you don't read all data, an other call to socket.recv
won't block.
socket.recv
will also end with an empty string if the connection is closed or there is an error.
If you want a non-blocking socket, you can use the select module (a bit more complicated than just using sockets) or you can use socket.setblocking
.
I had issues with socket.setblocking
in the past, but feel free to try it if you want.
It'll have the same behavior as the underlying recv libc call see the man page for an official description of behavior (or read a more general description of the sockets api).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With