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