TCP or UDP?

Started by
21 comments, last by kevmo 20 years, 4 months ago
I begun work on a multiplayer space fighter earlier this year (boring I know, but its the first steps towards what I hope to one day be a more interesting massively multiplayer game) and ran into problems with the network programming part of the game. My question is this: which protocol is better for online games designed for a large number of players, TCP or UDP? I pretty much know the differences: TCP has guaranteed delivery, thus being slower, but UDP has poor reliability despite being faster. I have been researching this issue for a while, and the consensus seems split. I realize that you can implement your own packet delivery system with UDP, but I have not attempted this yet, although it seems like the correct answer. Does anyone who has written a MMOG care to share his/her thoughts on this? Thanks, Kevin P.S. Yes, I have written tetris. And then some. P.P.S. No, I am not new to network programming, just network programming in a game.
Advertisement
http://www.gamasutra.com/features/19990903/lincroft_05.htm
Creation is an act of sheer will
There''s nothing stopping you from using both. Use UDP for timecritical stuff and TCP for the rest.
RonHiler, that article has one of my favourite lines:

"TCP is evil. Don’t use TCP for a game. You would rather spend the rest of your life watching Titanic over and over in a theater full of 13 year old girls."

-------
Andrew
PlaneShift - A MMORPG in development.
The only type of game I would use TCP for is RTS or other strategy games, because they don''t require super fast reaction time and reliability is a must. For other types of games, a custom UDP based protocol with selectable reliability is best.


Looking for a serious game project?
www.xgameproject.com

Looking for a serious game project?
www.xgameproject.com
quote:Original post by acraig
RonHiler, that article has one of my favourite lines:


Indeed. I''ve quoted that line myself once or twice before

Creation is an act of sheer will
Thanks all.

On a related note, how can I tell how calls to sendto() are split up into UDP packets? This seems important because UDP doesn't guarantee in order delivery, and it would be nice to know that a small quantum of data actually would be delivered as intended.

Edit:

I remember reading that article a while back, but it makes more sense now that I have learned more about network programming. What do people think about this part though:
"Our solution was simple and surprisingly effective. Every packet would send copy of the last packet. This way if a packet were dropped, a copy of it would arrive with the next packet, and we could continue on our merry way".

Is this a good approach, rather than actually resending packets, or perhaps in addition to?

[edited by - kevmo on December 16, 2003 11:33:56 PM]
quote:Original post by kevmo
Is this a good approach, rather than actually resending packets, or perhaps in addition to?

It''s one approach. It all depends on your requirements. The way they use is fine if it is absolutely necessary that each and every packet gets to its destination and in order (I presume they use some form of incremental ID value to order the packets). If your game has that requirement and can deal with the double bandwidth size (and remember with UDP you''re limited to about 512 bytes per packet for best results, which means with the double packeting you''re now down to 256 bytes of new data minus the header size), then yeah, it''s a pretty good method.

On the other hand, many games (mine for instance) don''t have this requirement. I find that certain types of packets need ordering *within themselves* (not necessarily with other kinds of packets), and many types are not critical to even get there as long as there are more of the same type on the way. Because of this, my implementation selectively (on a per packet type basis) allows for ordering of packets of a given type and/or reliability (which amounts to nothing more than buffering the packet data, ack packets and resends after a timeout period). This approach is commonly used in most UDP games, I think.

Creation is an act of sheer will
quote:
On a related note, how can I tell how calls to sendto() are split up into UDP packets?


They aren't. One UDP packet per sendto(), that's it.

quote:
The only type of game I would use TCP for is RTS or other strategy games, because they don't require super fast reaction time and reliability is a must.


Actually, that is questionable. Suppose the RTS uses a server approach where the actual unit movements are broadcast from a server to the clients (as opposed to synchronized simulation), it doesn't matter if one update from the server gets dropped, since the next update will fix it anyway.
Even if you are using synchronized simulation, I'd think twice about using TCP. It's simply hard to tweak and control (e.g. consider resending timeouts etc.).

If any type of game is suited for TCP, it would be round-based games.

cu,
Prefect

[edited by - Prefect on December 17, 2003 6:29:42 PM]
Widelands - laid back, free software strategy
quote:Original post by Prefect
They aren't. One UDP packet per sendto(), that's it.


Thats what I was afraid of. The thing that gets me is that I was taught to write a send() function similar to the following:

sendfunction(buf, size) {   bytessent = 0   while(bytessent<size)       bytessent += send(buf+bytessent, size-bytessent)}  


This way, the whole message gets sent in case send/sendto doesnt send all of the bytes. However, if there is only one packet per sendto, and packets aren't in order, couldn't that mess up some messages? Under what conditions would sendto not return that it sent all the bytes? Just when the size given is greater than 512 bytes less header size?

[edited by - kevmo on December 17, 2003 7:56:46 PM]

This topic is closed to new replies.

Advertisement