I have a problem in understanding what recv()/recvfrom() return from an non-blockig UDP socket.
A bit more specific and compared to TCP (please correct me if I'm wrong):
A blocking socket (either TCP or UDP) won't return from a recv() until there is some data in the buffer. This could be some number of bytes (TCP) or a complete datagram (UDP).
A non-blocking TCP socket either returns EWOULDBLOCK (linux) / WSAEWOULDBLOCK (windows) or the bytes that are currently in the buffer. As TCP data is a stream it doesn't matter how many bytes are returned.
Now the question:
Edit:
What I mean with "half of a datagram" is: what happens if I call recv() in just the moment when the socket is currently receiving a datagram. In that moment there are some bytes in the buffer but the datagram isn't complete yet.
Your explanations and comments are appreciated. Thanks!
Finally, an excuse to dig out my Stevens books from my old office boxes.
Provided the buffer is large enough, the standard Berkeley sockets recv()
and recvfrom()
functions will never return a partial datagram. The datagram is not available to the application until the kernel has completely received and reassembled the datagram.
Interestingly, and this isn't much (any?) of an issue today, other network programming interfaces don't agree on the behavior when the provided buffer is too small:
The traditional Berkeley version of the sockets API truncates the datagram, discarding any excess data. Whether the application is notified depends on the version. (4.3BSD Reno and later can notify the application that the datagram was truncated.)
The sockets API under SVR4 (including Solaris 2.x) does not truncate the datagram. Any excess data is returned in subsequent reads. The application is not notified that multiple reads are being fulfilled from a single UDP datagram.
The TLI API does not discard the data. Instead a flag is returned indicating that more data is available, and subsequent reads by the application return the rest of the datagram.
(Stevens, TCP/IP Illustrated, Volume 1, p. 160)
Yes, UDP just returns what data got transmitted in that one datagram. UDP is not stream-oriented like TCP. Datagrams are discrete transmissions, and are not really tied to other datagrams in any way. That's the reason the socket option for TCP is SOCK_STREAM.
The bright side of this is that you can get a sense of separate transmissions, which isn't really easy to do with TCP.
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