Advertisement

TCP or UDP?

Started by December 16, 2003 12:30 AM
21 comments, last by kevmo 21 years, 1 month ago
quote:


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.




Thats not true at all. RTS games usually involve endpoint based movement (ie: move this unit or this group of units from here to there). Such updates can be only sent once, saving bandwidth by avoiding to constantly send movement updates. RTS games also do not require a very fast latency, so TCP would be fine and actually advisable for RTS games. In such a system, the server also has much less to worry about, it simply checks the validity of client commands and broadcasts them once.

TCP would also be advisable for round based games of course.

I'm using my own UDP based protocol for my FPS game engine, but TCP definitely has a use in game development, its just more suited to specific game styles. Saying that TCP is evil and makes no sense at all for games simply shows a lack of knoweledge of real world networking and game development... There is no universal solution.



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

[edited by - Max_Payne on December 17, 2003 11:21:01 PM]

Looking for a serious game project?
www.xgameproject.com
quote:
Original post by kevmo
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?


Under no conditions, if I understand your question right. If you are using a blocking socket (usually a bad idea), the call will block until the enitre packet is sent out. If you are using some sort of completion notification (better idea) the call will return immediately, and you''ll get a completion notification once the whole thing has gone.

For that reason, there is no need for a while loop like you use in a send call.

My send function is very simple, it just sets up a couple of class variables and sends the buffer. It''s basically just fire and forget.

int BufferClass::SendBuffer(SOCKET *Socket, DWORD Address, u_short Port)    {    //set up the output socket info    Operation = OP_WRITE;    ZeroMemory(&Overlapped, sizeof(WSAOVERLAPPED));    ClientAddress.sin_family = AF_INET;    ClientAddress.sin_addr.s_addr = Address;    ClientAddress.sin_port = Port;    ClientAddressSize = sizeof(sockaddr);    Flags = 0;    return WSASendTo(*Socket, &WSABuf, 1, &NumBytes, Flags, (sockaddr*)&ClientAddress, ClientAddressSize, &Overlapped, NULL);    } 


Max:
No one is saying TCP is useless. Indeed, it is quite appropriate for most any turn based game. I even agree you *might* get away with it for an RTS depending on the game setup. But it is mostly inappropriate for games in general. Saying otherwise is just being unneccesarily contrary and argumentative.
Creation is an act of sheer will
Advertisement
RonHiler - thanks! you''ve cleared this issue up for me
Hi Kevin, I agree completely with the earlier posters, UDP is definately the way to go for any kind of game which requires real-time responsiveness. I''m currently writing a space combat MMOG myself, designed to be scalable over multiple servers it''s definately a good introduction to the intricacies of network programming

I notice you were having problems with send functions etc. with UDP, you can take a look at the network library I wrote for my project (which is a fairly early version and needs some extra features adding and some tidying up, but it works, and has all the essential components of a UDP-based reliable networking protocol). It''s available at http://www.clearchaos.com/netlib.php (although the site is down sometimes and bandwidth is fairly limited, since I''m hosting it on my own connection currently).

To comment on your idea of sending redundant copies of each packet; this could be a viable method in a game with few players, but given that most of the time you''ll be using twice the bandwidth you strictly need, may be a bad idea for games with many players, due to the cost and limited availability of bandwidth. A better solution might be to resend packets to a client if an acknowledgement for them is not received after a given amount of time (for instance twice the clients ping, or 500ms, or a time you devise using some other algorithm). This is especially true since there is no guarantee with your method that a client would receive a packet the second time, so surely some reliability method similar to the above would need to be implemented anyway?

Hope that''s of some help.
quote:
it''s definately a good introduction to the intricacies of network programming


Your telling me - I had a working (well not really in the end) version of mine that allowed players to fly around and see each other, and I discovered all sorts of subtlies I hadn''t seen in any of the articles here on gamedev. I scrapped the code in favor of a rewrite, and then came schoolwork, and so here I am now trying to plan things out better before I try again.
The sample chapter of Mud Game Programming, on the front page of gamedev (click), goes over the topic quite well. As previous posters have mentioned, TCP is more suited for games where packet accuracy is more important than speed such as RTS, and MUDs. UDP would be more suited for fast paced games like FPS and action games.

[edited by - vangelis on December 18, 2003 1:47:40 AM]
---------------------Ryan Bujnowicz[ vangelis ]
Advertisement
512 seems a bit small.

Ethernet II''s MTU is 1518 bytes (1526 bytes on the wire)
7 pre-amble, 1 start, and then ethernet packet

The ethernet II header is 14 bytes and there''s a 4 byte check-sum at the end.
6 src, 6 dest, 2 type, pay-load, 4 cs
(src & dst are your NIC''s MACs)
Maximum pay-load thus is 1500, and the minimum payload is 46 bytes.

IP header is typically 20 bytes (could be larger with options, but these are less commonly used - e.g. multi-casting), a bunch of crap followed by the source and destination IP addresses.

Remaining pay-load is 26 to 1480 bytes.

UDP header is an additional 8 bytes; src & dst ports, length, & a check-sum.
That leaves 1432 bytes for the payload max, and 18 bytes minimum.

UDP on ethernet II has a 50 byte overhead; to send 1 to 18 bytes of UDP data, you have to put 68 bytes on the wire.

In a few days I''ll be writing some UDP code, and I''ll check out how much data I can send over the LAN, WAN, & internet. I expect it to be 1432 bytes.

If the data goes through some crappy token-ring or arc-net then then I don''t know the MTU. Today, nearly everything uses ethernet locally (I guess I should update myself to 802.11 - what''s the MTU on the wireless ethernet?).
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
quote:
Original post by Psychor
Hi Kevin, I agree completely with the earlier posters, UDP is definately the way to go for any kind of game which requires real-time responsiveness. I''m currently writing a space combat MMOG myself, designed to be scalable over multiple servers it''s definately a good introduction to the intricacies of network programming

I notice you were having problems with send functions etc. with UDP, you can take a look at the network library I wrote for my project (which is a fairly early version and needs some extra features adding and some tidying up, but it works, and has all the essential components of a UDP-based reliable networking protocol). It''s available at http://www.clearchaos.com/netlib.php (although the site is down sometimes and bandwidth is fairly limited, since I''m hosting it on my own connection currently).

To comment on your idea of sending redundant copies of each packet; this could be a viable method in a game with few players, but given that most of the time you''ll be using twice the bandwidth you strictly need, may be a bad idea for games with many players, due to the cost and limited availability of bandwidth. A better solution might be to resend packets to a client if an acknowledgement for them is not received after a given amount of time (for instance twice the clients ping, or 500ms, or a time you devise using some other algorithm). This is especially true since there is no guarantee with your method that a client would receive a packet the second time, so surely some reliability method similar to the above would need to be implemented anyway?

Hope that''s of some help.




I started reading through your netlib, and one thing really jumped out at me:
#define MAXPACKETSIZE 1400 


Despite the last posters analysis leading to 1400 being a very reasonable number, I would feel a lot better if that were a constant based on getsockopt().

On the other hand, I like how you structured your different kinds of messages (RELIABLE X ORDERED).
quote:
Original post by RonHiler
quote:
Original post by kevmo
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?

Under no conditions


I found the resource where I got the notion that partial sends could occur: http://www.ecst.csuchico.edu/~beej/guide/net/html/advanced.html#sendall

Is that just plain wrong?

To kevmo:
There is a difference between send and sendto. Assuming you use send for TCP und sendto for UDP: If sendto would only send a little part of the message you would be in big trouble because UDP is unreliable. It does not help do send the rest of the Packet with another call to sendto because UDP does not garante that the Packets will be recived in order and therefor you will have trouble putting the package together again.
With send (TCP) it is a whole different story. TCP is a stream orientated Protokol and messages will be recived in the same order. So if send does not send everyting, you can send the rest with another call to send and you wont have any trouble putting it together on the reciver side (in fact, the reciver should not see any difference).
The bottom line is: If sendto would only send parts of the message (which can happen with send), you would be in big trouble. With send, it is no problem because TCP garuantes that the packages will arrive in order.

Sorry if may english is not to good, but I hope I was able to make clear to you what the difference is.

This topic is closed to new replies.

Advertisement