networking systems
Hello.
I am working on the networking code for my fast paced real time online action game. My current network code is setup identical to the flipcode networking article(http://www.flipcode.com/network/). At first, it seemed like it was setup very well and would work for my needs, so I went ahead with that design for my own networking(client and server side). But now that I have client login, disconnect, and chat working online, and try to add in support for online movement and weapon firing, it seems that alot of the packets aren''t getting recieved correctly(or something similar that is messing things up). But this only happens when i am trying to send alot of network messages at a time. With my current setup, logins, disconnects, and chat all work fine, but when I add movement and send out movement updates every second, and try to chat too, some of the chat packets seem like they aren''t recieved correctly. Now it seems like I can''t go any further until this problem is resolved, because if I''m losing data with just a one second update time, things will get much more messier when i start updating 10-20 times a second(which I plan to do) and add weapon update messages to the mix. I think there may be a problem with using the networking design from the article for my needs. My current code is setup to handle messages just like in the flipcode article. If it can recieve data, then it recieves the buffer and translate it into a message class based on its ID(first integer of the message) and then adds the message class into a linked list. Each server cycle the server checks the recieve queue and processes the next message that was queued. The send queue works the same way, except when you want to send data, you create a message class and add it to the queue and each server cycle the server checks the send queue, and if there is any messages in the queue, it sends the next one and removes it from the queue. I was wondering if this is the best way to do things or not, or if I should process all the send/recv messages in the queue every cycle, or just process one send and one recv message every cycle.
If someone could look at the code in the article and explain and weaknesses or strengths related to my problem it would be very benificial. Also, any statements about how you guys have your networking code setup(related to my problem) would be benificial too.
---===xxxx===---
----THE END----
---===xxxx===---
----THE END----
---===xxxx===---
Two things:
Firstly, if you just try to send data all of it might not get sent. Especailly on message based protocols like UDP where the packets are sent when they are full. Make sure that you get the return values from your send() commands, they tell you how much data has ACTUALLY been sent. You need to send the rest yourself by queing or buffering it (like in a sendq). Receiving is quite easy, just make sure you receive the entire packet, and if you havent then buffer it and check. Also, make sure to check that you dont receive multiple packets in one recv(), if you have you need to seperate them and process them seperately.
Secondly, not all packets will reach their destination in UDP, in TCP its guranteed to ALWAYS get to the destination but it could take a while to do that. In UDP, if packets dont get to their destination they will just be dropped and you wont know about it. You need make sure that whenever you send a packet that you acknowledge that you have got that packet on the client-side and if you dont get an ack from a client and your the server you must resend it until you get an ack or reject the client (because its not responding). This is actually one of the bad aspects of UDP, id suggest that if your new to networking then use tcp/ip. Its much easier and you get less control over everything.
So, all you need to do is make sure that if your using UDP/IP that you resend any packets that dont get from the client to the server or from the server to the client. And make sure that your packet decoding (seperating of packet blocks or buffering of fragmented packets) is working and that your send queing is working properly so that everytime you get a FD_READ message from your asynch window or select() call or thread read() (depending on how you get network messages).
Hope that helps
CorsairK8
Email me at CorsairK8@Fnemesis.com if you want any more help...
Firstly, if you just try to send data all of it might not get sent. Especailly on message based protocols like UDP where the packets are sent when they are full. Make sure that you get the return values from your send() commands, they tell you how much data has ACTUALLY been sent. You need to send the rest yourself by queing or buffering it (like in a sendq). Receiving is quite easy, just make sure you receive the entire packet, and if you havent then buffer it and check. Also, make sure to check that you dont receive multiple packets in one recv(), if you have you need to seperate them and process them seperately.
Secondly, not all packets will reach their destination in UDP, in TCP its guranteed to ALWAYS get to the destination but it could take a while to do that. In UDP, if packets dont get to their destination they will just be dropped and you wont know about it. You need make sure that whenever you send a packet that you acknowledge that you have got that packet on the client-side and if you dont get an ack from a client and your the server you must resend it until you get an ack or reject the client (because its not responding). This is actually one of the bad aspects of UDP, id suggest that if your new to networking then use tcp/ip. Its much easier and you get less control over everything.
So, all you need to do is make sure that if your using UDP/IP that you resend any packets that dont get from the client to the server or from the server to the client. And make sure that your packet decoding (seperating of packet blocks or buffering of fragmented packets) is working and that your send queing is working properly so that everytime you get a FD_READ message from your asynch window or select() call or thread read() (depending on how you get network messages).
Hope that helps
CorsairK8
Email me at CorsairK8@Fnemesis.com if you want any more help...
CorsairK8@Fnemesis.comLinux Debian/GNU RulezThis is my signitory!C Is Tha Best!
March 10, 2001 06:15 PM
First thing you need to do is to check that your networking code is functioning correctly. Make sure you''ve disable Nagels algorithim on TCP sockets. Once your conifident that your networking code is functioning correctly (no stalls due to multithreading locks, no buffer pointer error, etc..)you can move onto the really hard part 8^)
A multiplayer game usually encapuslates the networking components into a seperate module apart from the game logic. However, if your games logic isnt designed to be multiplayer friendly, dont exepct good performance over a high latency, lossy network enviroment (ie the internet). First you need to look into making your game multiplayer friendly. Thing which make your game multiplayer friendly :
-a clean event based system
-a variable update rate based upon time
-low update rates (on the order of 10 per sec)
-design the game logic as such that both the client and server use as much "common code" as possible. That is logic for movement should be exaclty the same for both the client and server. Design logic components to be toggleable to client or server mode.
Now with that done, you can move onto the network logic and interface.
I''ve found that each client needs an associated piece of game logic which i call the client entity handler. This handler class is basicly a state machine which manages clients. Its responsible for sending clients updates, responding to client commands etc..
As your game evoles so will your packet protocol. Like with any optimization dont optimze your packet protocol until you really need too. Start with fat packets and work your way down, truncating data, reducing reduncany etc..
I''ve found that if you reduce your games bandwidth usage enough, TCP is as good as UDP in cases of people with highspeed connections.
The interface between the multiplayer code and the game logic can be encapsualted into a middle layer. This proxy layer allows you to redirect events for a single player game into the network stream instead. Allowing you to build your multiplayer game form a strong singleplayer game base (which you can toggle between) This has been very useful for me, I think you will also find it valuable.
Good Luck
-ddn
A multiplayer game usually encapuslates the networking components into a seperate module apart from the game logic. However, if your games logic isnt designed to be multiplayer friendly, dont exepct good performance over a high latency, lossy network enviroment (ie the internet). First you need to look into making your game multiplayer friendly. Thing which make your game multiplayer friendly :
-a clean event based system
-a variable update rate based upon time
-low update rates (on the order of 10 per sec)
-design the game logic as such that both the client and server use as much "common code" as possible. That is logic for movement should be exaclty the same for both the client and server. Design logic components to be toggleable to client or server mode.
Now with that done, you can move onto the network logic and interface.
I''ve found that each client needs an associated piece of game logic which i call the client entity handler. This handler class is basicly a state machine which manages clients. Its responsible for sending clients updates, responding to client commands etc..
As your game evoles so will your packet protocol. Like with any optimization dont optimze your packet protocol until you really need too. Start with fat packets and work your way down, truncating data, reducing reduncany etc..
I''ve found that if you reduce your games bandwidth usage enough, TCP is as good as UDP in cases of people with highspeed connections.
The interface between the multiplayer code and the game logic can be encapsualted into a middle layer. This proxy layer allows you to redirect events for a single player game into the network stream instead. Allowing you to build your multiplayer game form a strong singleplayer game base (which you can toggle between) This has been very useful for me, I think you will also find it valuable.
Good Luck
-ddn
What happens when a packet is dropped?
Magmai Kai Holmlor
- The disgruntled & disillusioned
Magmai Kai Holmlor
- The disgruntled & disillusioned
- 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
March 11, 2001 01:03 PM
There are several major problems which arrise when you try to syncronize the client and server, packet loss and large packet latency variance. Packet loss can be compenstated by finding a good level of redundancy, usually increasing the rate of update by a small percent 10%, or going with a variable update scheme, where you dynamaicly increase the rate of update based upon line connection vs bandwidth consumption vs loss etc.. One way packets can be loss is the overflow of the reciving buffer. For udp connections when the recive buffer overflows i think the incoming packets are dropped. So if you diligently consume all incoming udp packets, that potential for loss is reduced. Keeping your udp packets small (after you collate them per update ofcourse, so you reduce the overhead of sending many small packets), can help reduce loss as well.
However i''ve yet to encounter major loss, proably becuase i keep my packets very small and make sure to call recive on all incoming udp packets asap. The other major problem with synchronization is large latency variance. Any synchronziation algorithim which doesnt take into account packet variance, will result in either many timeout packets or really jumpy gameplay. Timeout packets are those which arrive too late for the current local machines timestep. The data is just too old to be used. Using some form of buffering would help or extrapaltion.
Good Luck
-ddn
However i''ve yet to encounter major loss, proably becuase i keep my packets very small and make sure to call recive on all incoming udp packets asap. The other major problem with synchronization is large latency variance. Any synchronziation algorithim which doesnt take into account packet variance, will result in either many timeout packets or really jumpy gameplay. Timeout packets are those which arrive too late for the current local machines timestep. The data is just too old to be used. Using some form of buffering would help or extrapaltion.
Good Luck
-ddn
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement