Receive an entire UDP datagram, regardless of size?
Asked Answered
D

1

9

Consider 100 bytes sent across a socket. With a TCP socket, if I call recv() with a length of 50, I get the first 50 bytes, and if I call it again, I get the second 50 bytes. With a UDP socket, if I call recvfrom() with a length of 50, I get the first 50 bytes, but then have no way of retrieving the second 50 — subsequent calls to recvfrom() block until the next datagram is received.

Does this mean that, if I want to receive an entire UDP datagram, regardless of size, I have to allocate a 64k buffer (the maximum allowed by UDP)? If I connect() my UDP socket, does this change the behavior? Or does a protocol operating over UDP generally entail a known maximum packet size that should be used for a buffer?

Dickman answered 13/9, 2012 at 16:52 Comment(0)
M
3

Most sane UDP-based protocols don't go over MTU less IP and UDP header to avoid IP fragmentation. E.g. DNS switches to TCP for messages bigger then 512 bytes. So you are probably safe with a buffer of 1472 bytes (1500 Ethernet MTU - 20 for IP header without options - 8 UDP header), unless your network uses jumbo frames. This of course depends on the application protocol on top of UDP.

If you are really paranoid (or working with unknown protocol) you can use MSG_PEEK and MSG_TRUNC flags to first figure out the size, and then allocate big enough buffer (see recv(2)).

Monthly answered 13/9, 2012 at 17:34 Comment(1)
MSG_TRUNC does not seem to be defined as an input flag on FreeBSD (freebsd.org/cgi/man.cgi?query=recv&sektion=2)Turnbull

© 2022 - 2024 — McMap. All rights reserved.