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
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