Tcp – Does implementing some level of reliability in UDP packets defeat its purpose over using TCP

layer4tcpudp

Considering UDP packets can get lost or arrive late to their target destination, does it make more sense to:

  • Use a TCP socket for important messages & events (ex: in a game where a player gets hit, attacks, dies, picks up item, saves the princess, etc.),

    OR…

  • Should a "reliability system" of some sort be developed in your UDP packets structure to confirm the reception of those particular events?

It seems that, at a minimum, for the few bytes difference that TCP have over UDP (min of 64b vs 52b, so 12b apart, according to this answer: https://stackoverflow.com/a/1846139/468206 ) that it would make more sense to let a TCP connection handle those events rather than re-invent the wheel in UDP. But maybe I'm missing the point?

Does keeping a TCP connection alive in the long-term / the duration of an app / game (let's say a minimum of 15mins) apply some overhead that can't be easily reduced or controlled as well as a custom-made "reliable" UDP implementation?

Would the bytes savings be more apparent in UDP because, for example, the reliable-event message in question could have some unreliable data piggy-back to it? (unreliable data = as in, basically any piece of data that would normally omit sending the extra "reliability" bytes, using a Fire-and-Forget approach)?

Note: There's probably some aspects of TCP that I forgotten or didn't take in consideration, which is why I reach out to you lovely experienced network developers to help bring up and drive the point home! 🙂

Best Answer

Considering UDP packets can get lost or arrive late to their target destination, does it make more sense to: Use a TCP socket for important messages & events (ex: in a game where a player gets hit, attacks, dies, picks up item, saves the princess, etc.),

OR... Should a "reliability system" of some sort be developed in your UDP packets structure to confirm the reception of those particular events?

In short, neither.

There are a lot of resources online discussing precisely this (real-time protocol design, especially in gaming), but to summarise, the model whereby one host acts as a "server" and keeps track of game state (all players, statistics and object state in a world), and all clients communicate with the server via UDP is the industry standard.

UDP connections are used because you negate any round-trip latency associated with connection set-up or segment acknowledgement.

Because you have a server tracking state, it doesn't need to care about the client receiving frames or not - the client and server just send deltas, which they then update from the last known state.

This is of course an over-simplification of a very complex topic, but the gist is that there is no need for upper-layer protocols to be hacked over the top of UDP to make it "reliable" - the nature of real-time traffic, is that it is worthless if not delivered within a very short window.

I highly recommend the following article discussing experiments and observations by John Carmack when writing the Quake 3 networking code:

http://trac.bookofhook.com/bookofhook/trac.cgi/wiki/Quake3Networking