Advertisement

How2Ensure UDP-Packets reach target (high performance)?

Started by December 08, 2014 02:40 PM
13 comments, last by Dave Weinstein 9 years, 11 months ago

Another method is : on packets (with sequence ID used both directions) to include a Start ID+bitmap (like 32 bits) of the ACK status for a 'window' of the previously recieved packets in the sequence (with appropriate bit masks

/sequence /packet buffer chains maintained for the packet flow in each direction).

Thus every send has ACK data for a whole bunch of previous packets and unless something very bad is happening that ACK info should get through to be acted upon. You have the sender hold onto the unackknowledged packets to do resends (repeatedly if needed) on some delay schedule.

Again you watch the resend activity and if the whole connection is getting dodgy you start taking other contingencies to compensate (including calling upwards to the Application level for more drastic measures).

Likely you also have keep alive packets timed to be sent if there is no App data traffic, so the ACK bitmaps get throiugh and the programs can continuously monitor the connection status.

By that point you are replicating what many of the Reliable UDP libraries do (though a reason to roll your own is for added customizations for performance and added functionality ).

--------------------------------------------[size="1"]Ratings are Opinion, not Fact

Have you considered using two connections in your game?

Establish a TCP connection for events that are high-latency and not important, but where order of messages and gauranteed delivery is required (e.g. chat events, downloading assets) and use UDP datagrams for anything that doesnt require the gauranteed delivery or ordering, such as player position updates etc, using the sequence numbering and brute force approach outlined by others above.

Advertisement
The dual-connection option doesn't work that well for NAT punch-through scenarios.
If you run all the servers, that doesn't matter.
Another problem with TCP used to be that it would send large packets, which would cause significant jitter for other traffic (such as the UDP stream.) As links get faster, that effect lessens. (It was a non-starter on dial-up...)
enum Bool { True, False, FileNotFound };

The dual-connection option doesn't work that well for NAT punch-through scenarios.


Absolutely true.

Another problem with TCP used to be that it would send large packets, which would cause significant jitter for other traffic (such as the UDP stream.) As links get faster, that effect lessens. (It was a non-starter on dial-up...)


Actually, it worked really well on dial-up, because TCP supports header compression, and UDP does not. And dial-up was very much of a bandwidth last-mile issue. Also the moment you actually have ordered-reliable transmission, you might as well take advantage of it for delta compression.

The model of an ordered-reliable TCP channel and an unreliable UDP channel was exactly the model used in Rainbow Six and Rogue Spear. It was dropped later in favor of a purely UDP model (including both ordered reliable and unreliable logical channels) specifically because, as you noted earlier, you cannot punch through NAT with TCP.

I should note that the R6/RS model was opposite of what was proposed. Almost everything went over the reliable channel, the only thing that went over the unreliable channel were movement updates for entities that were "near" the recipient.

This topic is closed to new replies.

Advertisement