Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding how to send larger data chunks over UDP reliably

I've used TCP for many things over the years and understand it pretty well. I now have a requirement to use UDP.

Short version: A server allows a small number of clients (5-10) to connect. The server is running a simulation. Clients should be able to update parameters for the simulation and see (a subset) of the simulation results.

In this instance, timing (when the parameters change) is important and the delay between the client requesting a change and it being implemented must be as low as possible.

I've been doing a lot of reading and I'm still not "getting it".

Can someone please confirm/deny my understanding...

  • A datagram is stored inside a single packet
  • The largest payload I can reliably send is 506 bytes (576 MTU - 60 IP header - 8 UDP header)
  • Sending more than that may cause fragmentation
  • Fragmentation isn't handled at a lower level and would require me to recombine datagrams (Not sure about this - if it's handled automatically, why do I care about fragmentation?)
  • I need to implement my own ACK/Throttling mechanism

So... If I want to send (say) 800 bytes of data from the client to the server, I need to:

  • Determine an arbitrary "Protocol" id to be used represented by a Byte(2) that is common between client and server and is used to filter out messages not meant for my app.

Client

  • Create a random message id
  • Split the data into two, add the message id and a global sequence so they can be rejoined at the other end
  • Record the data against the sequence id somewhere in memory
  • Send them to the server
  • If an Ack isn't received in a given timespan (Say RTT * 3), resend that packet.

Server

  • Inside simulation loop, check (non-blocking) if there is a message on the socket.
  • If so, immediately send back a new packet containing an ACK for the sequence Id (actually, to mitigate Ack packet loss, I should Ack the last 30 or so received packets)
  • Store the packet in memory until I've received the 2nd half
  • Combine the two and process the payload

For messages going in the other direction, I need to do exactly the same in reverse.

I can't help feeling I'm missing something and don't quite understand the implications of a packet fragmenting. Can someone please clarify / point to a better resource?

like image 544
Basic Avatar asked Jan 18 '26 19:01

Basic


1 Answers

  • A datagram is stored inside a single packet

Not necessarily.

  • The largest payload I can reliably send is 506 bytes (576 MTU - 60 IP header - 8 UDP header)

Incorrect. The IP header is 20 bytes, not 60, so the total header is 28 bytes. That leaves you 576-28=548, but the number usually bandied around is 534.

  • Sending more than that may cause fragmentation

Yes.

  • Fragmentation isn't handled at a lower level and would require me to recombine datagrams (Not sure about this - if it's handled automatically, why do I care about fragmentation?)

Incorrect. Fragmentation is handled completely at the IP level. The problem with fragmentation in UDP is that there is no ACK/retransmit mechanism for lost fragments, so one lost fragment means the entire datagram is lost. What you see is either an entire UDP datagram or nothing.

  • I need to implement my own ACK/Throttling mechanism

Yes. A simple ACK/retry scheme is given in W.R. Stevens, Unix Network Programming, vol I.

like image 183
user207421 Avatar answered Jan 20 '26 20:01

user207421



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!