75

From test, I concluded that in following three cases the socket.recv(recv_size) will return.

  1. After the connection was closed. For example, the client side called socket.close() or any socket error occurred, it would return empty string.

  2. Some data come, the size of data is more than recv_size.

  3. Some data come, the size of data is less than 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?

4
  • 1
    docs.python.org/library/socket.html#socket.socket.recv Commented Aug 24, 2011 at 11:53
  • 16
    Thanks, but the manual did not answer my question. Commented Aug 24, 2011 at 11:57
  • 3
    How about here: linux.die.net/man/2/recv Commented Aug 24, 2011 at 12:02
  • I don't think your #2 case should ever happen. If recv() is returning more than the number of bytes your specified in the argument you passed in, that is a bug. (Btw for #3: sleeping to wait for more data is a bad idea, it will make your I/O routines slower than they need to be.... you should use an event-driven approach instead, either something like select(), or blocking I/O calls) Commented Aug 24, 2011 at 17:00

3 Answers 3

55

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.

Sign up to request clarification or add additional context in comments.

8 Comments

I didn't see any official description about my conclusion 3).
socket.recv will read what is ready to be read when the call to recv is made. It does not matter if the amount read is less than the max size, the socket will unblock as soon as it can read data.
You can also call recv() as nonblocking if you give the right flag for it: socket.recv(10240, 0x40) # 0x40 = MSG_DONTWAIT a.k.a. O_NONBLOCK Please note that you have to catch the [Errno 11] Resource temporarily unavailable exceptions when there is no input data.
when I am doing msg = socket.recv(1024), then len(msg) is 1024. However, when I do msg = socket.recv(10485760) (10 MB), then len(msg) is 8760...why this can be? Is it like input socket buffer has max size of 8760 bytes, and hence, whenever we try to read more data than 8760 bytes, it still returns only 8760 bytes
the parameter to socket.recv is the maximum length of the message to read at once. It will try to read up to that number, but no more, then return the read value. If you expect to receive more data than that, you can try to recv later on, or wait for more data to be received before calling the recv method.
|
4

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).

Comments

2

I think you conclusions are correct but not accurate.

As the docs indicates, socket.recv is majorly focused on the network buffers.

When socket is blocking, socket.recv will return as long as the network buffers have bytes. If bytes in the network buffers are more than socket.recv can handle, it will return the maximum number of bytes it can handle. If bytes in the network buffers are less than socket.recv can handle, it will return all the bytes in the network buffers.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.