4

I am implementing a simple network stack using UDP sockets and I wish to send about 1 MB of string data from the client to the server. However, I am not aware if there is a limit to the size of the length in the UDP sendto() API in C. If there is a limit and sendto() won't handle packetization beyond a limit then I would have to manually split the string into smaller blocks and then send them.

Is there a limit on the length of the buffer? Or does the sendto() API handle packetization by itself.

Any insight is appreciated.

P̲̳x͓L̳
  • 3,615
  • 3
  • 29
  • 37
user2058668
  • 231
  • 1
  • 3
  • 12
  • http://stackoverflow.com/questions/25841/maximum-buffer-length-for-sendto – mkimball Mar 31 '14 at 22:30
  • It should handle any length, but: Be aware that each packet in UDP could arrive wrong (not at all or multiple times or paket order shuffled). And you can´t know in advance where your data is splitted into packets... – deviantfan Mar 31 '14 at 22:30
  • FYI: http://pubs.opengroup.org/onlinepubs/009695399/functions/sendto.html says sendto sets `errno` to `EMSGSIZE` if the message is too large. So, if you really need to, you can do it all dynamically, and see if the data is too large. Something makes me think 1MB will be too large.. – Gábor Buella Mar 31 '14 at 22:34
  • If you use UDP, you have to handle splitting into UDP packets yourself. Splitting and reassembling of IP Packets must be supported for your full packet length and segment count though, both on sender and receiver side. The relevant RFCs give minimal supported limits, the rest depends on the actual deployed hardware and software. Also, the MTU depends on the network. – Deduplicator Mar 31 '14 at 22:48

1 Answers1

9

There's no API limit on sendto -- it can handle any size the underlying protocol can.

There IS a packet limit for UDP -- 64K; if you exceed this, the sendto call will fail with an EMSGSIZE error code. There are also packet size limits for IP which differ between IPv4 and IPv6. Finally, the low level transport has an MTU size which may or may not be an issue. IP packets can be fragemented into multiple lower level packets and automatically reassembled, unless you've used an IP_OPTIONS setsockopt call to disable fragmentation.

The easiest way to deal with all this complexity is to make your code flexible -- detect EMSGSIZE errors from sendto and switch to using smaller messages if you get it. The also works well if you want to do path MTU discovery, which will generally accept larger messages at first, but will cut down the maximum message size when you send one that ends up exceeding the path MTU.

If you just want to avoid worrying about it, a send of 1452 bytes or less is likely to always be fine (that's the 1500 byte normal ethernet payload max minus 40 for a normal IPv6 header and 8 for a UDP header), unless you're using a VPN (in which case you need to worry about encapsulation overhead).

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
  • +1 You also get EMSGSIZE in UDP if the length exceeds the size of the socket send buffer. The actual upper limit for UDP in IPv4 is 65507 bytes (65535-28). – user207421 Apr 01 '14 at 00:03
  • thanks for the insight every one! But I am not a networking major and I am not very well versed in a lot of things related to UDP. I have a very basic understanding of UDP. How do I find out the maximum length buffer that I can pass to the sendto() function prior to running the code and obtaining an error? – user2058668 Apr 01 '14 at 20:15
  • @user2058668: the point is that you can't really -- the number may change if someone somewhere on the network between you and whoever you are talking to changes something. – Chris Dodd Apr 01 '14 at 21:31
  • so is there a way to do this? If so, can you point me in the right direction? – user2058668 Apr 01 '14 at 23:37