Socket recv() problem

Jake Speed speed at ?.com
Fri Oct 20 09:32:19 EDT 2000


cgaebler at gmx.de (Carsten Gaebler) wrote in <39F0321A.24D58DD4 at schlund.de>:

>Hi!
>
>It seems to me that a socket's recv() function doesn't read any data in
>subsequent calls when called repeatedly. I have the following sending
>and receiving programs:
>
># receiver
>import socket, sys
>sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
>sock.bind("/tmp/to_hell.sock")
>while 1:
>    sys.stdout.write(sock.recv(10))
>
># sender
>import socket
>sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
>sock.connect("/tmp/to_hell.sock")
>s = "0" * 100
>sock.send(s)
>
>
>The receiver prints out only the first 10 "0"s, the rest seems to be
>ignored. What's happening here?

You're using datagram sockets.

When you send() on a datagram socket, the string is sent
as a discrete packet -- a datagram.  When you recv() on
the destination socket, you read one, and only one datagram.
If your buffer is not large enough to hold the entire 
datagram, the rest is lost.

I think datagrams are limited to 64K in size, so if you
just do sock.recv(0x10000) you'll be ok; the string is 
automatically truncated to the actual size of the datagram.

If you were using stream sockets (SOCK_STREAM), then there
would not necessarily be a one-to-one correspondence between
calling send() and sending a single packet. The recv() call 
would read as much data as was available, up to the buffer size, 
and none would be lost.  If your data is not logically broken
up into packets, this would be a better idea.

Even if it is divided into packets, you can still use SOCK_STREAM
if you have some way of delimiting packets.  If you are sending
strings that do not contain newlines, you can send a newline after 
each logical packet.  If you are sending raw binary data, you
can send the packet length first, and at the destination 
receive it and then call recv() with the packet length.

-Speed!



More information about the Python-list mailing list