Multiplayer Game UDP/TCP Combo System
I am currently attempting to make my first graphic multiplayer game, but have run into a bit of trouble concerning server design.
Background: The game is a 2D top down shooter
I originally was going to use TCP because that is what I knew, but then I learned about UDP and it seemed to make more sense for real time game data, so I began to design a system that would use TCP for reliable data (chat messages) and UDP for game states (object positions,rotations,etc.) but ran into a problem with UDP. Since it has no "connections" I found that when testing locally if the server and client were on the same machine they would steal each others messages. The server would send a message but it would be received by the server because it too was listening on that port, or the client receiving its own messages. Then I realized this would pose a similar problem if two people were playing from within a LAN and therefore have the same external IP, how would I send data to either of them individually?
These problems make me want to switch to a TCP system but I worry that will cause a slow down in game FPS. Can anyone give me some advice? This is my first time trying this.
Note: Currently using boost::asio library for networking on Windows
Hi brwarner-
UDP is a fine choice. I'm running the same set you mention (client and server on same host using UDP for communication) and I don't have packet stealing.
You may want to verify each is using a different port! I'm guessing that's the problem here.
-Thomas
UDP is a fine choice. I'm running the same set you mention (client and server on same host using UDP for communication) and I don't have packet stealing.
You may want to verify each is using a different port! I'm guessing that's the problem here.
-Thomas
...I should really have thought of that shouldn't I... :(
Thanks for your help :)
Actually while I'm here I had another question as this is my first multiplayer game programming experience. When it comes to the server, how should it's game loop run? Should it simply run constantly updating the game (i.e updating position based on velocity and time and such) and hence have to send many client updates? This seems a bit innefficient as the clients game loop will be much slower and as a result will get many game state updates in just a single loop. (By run constantly I mean while(isRunning) { Update(); } ).
Also, one last question about UDP. Using different ports for both the client and the server addresses the problem of them "stealing" each other's messages (for instance client listens on port X while server listens on port Y) but what about if two users are behind the same router? Since it is connectionless if I simply send a packet towards them how would it know which computer to route to?
Thanks for your help :)
Actually while I'm here I had another question as this is my first multiplayer game programming experience. When it comes to the server, how should it's game loop run? Should it simply run constantly updating the game (i.e updating position based on velocity and time and such) and hence have to send many client updates? This seems a bit innefficient as the clients game loop will be much slower and as a result will get many game state updates in just a single loop. (By run constantly I mean while(isRunning) { Update(); } ).
Also, one last question about UDP. Using different ports for both the client and the server addresses the problem of them "stealing" each other's messages (for instance client listens on port X while server listens on port Y) but what about if two users are behind the same router? Since it is connectionless if I simply send a packet towards them how would it know which computer to route to?
Quote:Original post by brwarner
Then I realized this would pose a similar problem if two people were playing from within a LAN and therefore have the same external IP, how would I send data to either of them individually?
Quote:Original post by brwarner
but what about if two users are behind the same router? Since it is connectionless if I simply send a packet towards them how would it know which computer to route to?
NAT.
I also switched to udp a little time ago.
for important messages you should check for duplicate or lost messages. my application uses an id for each important message. for example host sends
id=42
...message...
when client recieves the message it replies it with. client replies with
42 recieved
if it does not get a reply for a time, it resends the message. also clients compares the id of the message with previous ids. if they already got one with the same id, it is a duplicate so it discards it
I am using winsocks and on the same computer it uses different ports for each client. I think this will be the case for the computers behind the same route
for important messages you should check for duplicate or lost messages. my application uses an id for each important message. for example host sends
id=42
...message...
when client recieves the message it replies it with. client replies with
42 recieved
if it does not get a reply for a time, it resends the message. also clients compares the id of the message with previous ids. if they already got one with the same id, it is a duplicate so it discards it
I am using winsocks and on the same computer it uses different ports for each client. I think this will be the case for the computers behind the same route
Quote:Original post by mattd
NAT.
I still don't understand how if two computers behind a router are connected to an external server via UDP can receive individual messages... From what I know UDP is connectionless so all I can do is send to their external ip address and wonder which computer it will go to.
Messages from two computers behind a NAT will appear to have come from the same IP address, but a different port.
Quote:Original post by brwarnerQuote:Original post by mattd
NAT.
I still don't understand how if two computers behind a router are connected to an external server via UDP can receive individual messages... From what I know UDP is connectionless so all I can do is send to their external ip address and wonder which computer it will go to.
Looks like you're forgetting that there is a port number associated with each session too.
Maybe this will help. (Sorry for all the Wiki links, but they have good explanations already :])
So this is done by the router itself? And all I have to do is respond to the same port as the messages are received and all will be well?
If so thanks, that would make this whole thing make a lot more sense.
If so thanks, that would make this whole thing make a lot more sense.
Yes. It's transparent (as long as you don't doing something silly like get the client to send its (LAN) IP address in a packet, because this will be in a UDP packet payload, not header, and therefore won't be caught and translated by the router. FTP has this problem, see here).
Also, if you're going to run a server behind NAT, you generally have to manually add mappings in the NAT configuration of your router. But then to clients contacting the server externally, once again it's transparent.
Also, if you're going to run a server behind NAT, you generally have to manually add mappings in the NAT configuration of your router. But then to clients contacting the server externally, once again it's transparent.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement