UDP packet out of order- behavior in real life ?

Started by
14 comments, last by hplus0603 3 years, 1 month ago

Am considering different ways of catching up from packet-out of order without knowing prehand how this problem ‘feels’ like as i dont have any run statistics yet ?

But i was watching this video :

Where he briefly touches down on their experience with packets out of order and he says : "its not all over the place that packets out of order is often just a switched sequence:

So ex if i have 100 packets with number 1 to 100 then is it correctly understood that i wouldnt get in a situation where i get packet no 100 first and then packet 9 and then packet 88 etc or can you expect this completely random order ?

And in case you can exepct that things come in total different order - how do you guys handle this buffer wise ? do you have a magical time interval of XX millseconds where you allow the buffer to order whatever it can order in that time before you process it ?

Advertisement

Let's say if u were getting 25 udp packets per second in a 25FPS scenario:

(P1, P2, P3,….. P10, P11, P13, P15, P12, P14 …. P20, P21, P23, P24, P25) per second:

  • if your app processes 25packets after each second, then all u need to do is sort this list every second and process them
  • if your app processes each packet as they arrive then depending on what your app's use-case is trying to achieve:
    • UC1: when u receive P13 after P11, u can process P13, but when P12 arrives just discard it
    • UC2: when u receive P13 after P11, u can hold P13, and wait for N packets in hope of receiving P12, if it arrives within N packets then process P12, P13 etc… if it doesn't arrive then process P13 (discard P12 whenever it arrives in the future). Same deal for P15 (waiting for P14)
    • UC3: when u receive P13 after P11, you can time the arrival of each packet, so if for ex P12 within the next 40ms then process P13 and discard P12 when it arrives in the future
    • etc…
  • etc…

point being, it is your responsibility to establish some rules for your incoming data packets; and if your packets have no inter-related dependency then the easier the decision;

For example:

  • Case A: a player increasing her car speed: these packets would contain current incremental velocity/accelaration values of speed
  • Case B: a player teleporting to various places: these packets would contain the current positional values (as opposed to incremental) of location

Case A could be treated with UC1, UC2 or UC3, whereas case B would be treated with UC1 only (ideally)

so it's all in your hands ;-)

I'm missing something. Why not use TCP?

taby said:
I'm missing something. Why not use TCP?

because it may not be viable for the type of game you're writing, for example for a multiplayer FPS, TCP would be a killer;

that's what you're missing -lol-

I realize the necessity of UDP, but why are out of order packets a problem in the first place, when surely you include the time stamp data inside the packet?

yes u can insert timestamp or sequencing into packets but the UDP Protocol does not guarantee that any packets will arrive at their destination in the same order as they were sent, let alone even arrive at all (some packet losses are usually expected with UDP). UDP is connectionless, so it offers no mechanism to acknowledge the reception of packets as TCP offers with ACKs etc…

Ok, got it.

So why is it a problem? All you have to do is ignore old packets altogether.

taby said:
So why is it a problem? All you have to do is ignore old packets altogether.

yes you can ignore if your use-case is fine with this (UC1) or not ignore and wait a little before ignoring in some other cases (UC2 or 3), see my earlier answer…

Yes, thank you for the distillation of your earlier answer.

Note that “waiting a little bit” means that you introduce additional network latency proportional to how much you wait.

The reason is the same as for TCP: head-of-line blocking. You have a packet that already arrived, but you're not paying attention to it yet because you're waiting for an earlier packet to arrive. There are cases where throughput matters more than latency, where this may make sense, but in 99.9% of such cases, TCP is the right choice.

There's another case to consider, too: IP fragmentation and reassembly. The maximum size UDP packet is 65535 bytes, but the underlying IP transport very likely has a smaller MTU, and thus your single UDP packet gets split into many fragments, and reassembled at the destination. This is invisible to you, but it, too, may introduce packet re-ordering delay, for larger packets. Separately, if you need to send individual messages larger than 64K-1, you will need to do the same kind of split and reassembly yourself. (RakNet does something like this.) At that point, it may make sense to use an error correcting code; send slightly more data, but be able to recover when you have (N-1) or (N-2) packets received.

In general, though, if you're prepared to “wait a little bit” after receipt, you should probably just use TCP.

enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement