UDP problems, theory, and suggestions

Started by
8 comments, last by KyleL 20 years, 4 months ago
This question is one I’m sure has been asked before, in fact I searched the forum and read the pervious ones over. But still, I feel I need to get an answer for myself. Making a game is a big task, and for an online game this is the one of the biggest parts. My question: This is going to be my first project ever really using UDP. Of course with UDP packets may not make it to the server, or even make it there more than once. I’ve not really found any documentation on how others solved this problem. Well, except one that I think can’t be too good. Some people say get a reply for each message you send in an acknowledgement (“ack”) packet. This would cause a lot of extra bandwidth and maybe even cause some lag while a client/server is waiting around to see if the other end got the message. Of course I realize they meant use an ID system so you can identify each packet so you could send more than one at a time. My idea was a little different than that, but I’m not sure its much better really. There would be different classes of messages. Each class has its own ID set. Each packet gets a new ID number for the class it is. Now, to sync it up the ping packets will send the last packet id’s for each class they’ve gotten. If the application has missed any of the packets will then be reissued. This means that messages for each class could be sitting in a queue for ping * number of lost packets + (bytes / speed) + time to next ping. I don’t like the idea of that too much. (The ping would be like once every 5 seconds) Most of these packets need to be received / processed in order. Any of you have any other suggestions? Any possible references you can give me? Thanks a lot guys Kyle
Advertisement
Well there are several things I''ve been using:

1. Piggyback the ACK, as in, the ACK for a previous packet will come attached to a packet that needed to be send anyway.
2. Divide everything in need to know and not that important, only ACK things that are need to know
3. Use checksums and base the next packets checksum on the previous one(s)

Those are some quick ones, just don''t go rewriting tcp or you might as well use that.
---Yesterday is history, tomorrow is a mystery, today is a gift and that's why it's called the present.
Thanks for the suggestions, Siaon. Nah I don''t have any TCP in it yet, get getting the connection part right now. Thanks again
Take a look at RFC908 for how reliable UDP communication is done. It''s probably the best *explained* reliable UDP standard there is (albeit not the best *performing* one).

http://www.faqs.org/rfcs/rfc908.html
I experimented with something similar to what you describe for my network library (I didn''t exactly use classes, different classes, but I tried 16 different reliability streams, all with their own ID sequences). In practice I found that the performance/RAM hit for managing reliability windows for all of the streams appeared to outweigh the performance gain (doesn''t block other streams waiting for sends when packets are lost). This is especially true since this method uses extra bandwidth normally sending extra identifiers/sequence numbers, and you only gain in performance when packets *are* lost, I find that over the Internet, pockets of lag where all packets are lost are much more common than consistent packet loss, hence packets would tend to be lost from lots of streams at the same time, with little performance gain. I do intend to implement high and low priority packets at some point though, to improve playability on low bandwidth connections.

Another trick to speed things up a little (at the cost of some bandwidth occasionally) would be to resend unacknowledged packets after a certain delay, rather than waiting for an acknowledgement from the other side to verify they have not arrived. You could do this after say (Ping * 1.5 * Number of resends of packet already), so if the client is responsive and a packet is lost, they should get it again pretty quickly, whereas if the client is unresponsive, the packet will be resent less and less frequently, so you don''t use excessive bandwidth resending to someone who has disconnected.

It''s possibly a little messy, and I need to make a few changes, but you can download the Beta code for the network API I''ve been working on from here.

Hope that''s of some help.
Psychor the link you game me appears not to work, thanks you very much for your information. If you could get a working link up (if the current one isnt working or is in correct) I''d be greatful.

Anonymous poster thanks for the RFC link, I actually hadn''t read that one yet. Interesting to see it was written a couple months before I was born, but hey that justs means the information needed to be more optimized

Thanks a lot to the both of you.
Hey I just wanted to get back to you last two guys after I''ve had some time to work a little bit with both of your suggestions.

First, I like RFC 908 a lot. I''m not going to use RDP for my game though, but it did give me a little more inspiration. A couple of the ideas in there were kind of sexy.

Psychor I''ve been looking over your netlib library too. First thing I should point out something to you. You use a couple of fors with PingArraySize and you''re using an integer for the counter. PingArraySize is unsigned, MSVC++ 7 wasn''t too happy with that. But besides that its an interesting system, I may have used it if I hadn''t gotten a couple ideas from the pervious mentioned RFC.

Thanks again to both of you

Oh hey in my pervious message I was saying that the RFC was made before I was born so it had most-likely would of had to be ''more optimized'' .. I was reffering to slower netconnections back then.
why reinvent the wheel?
why not use something like enet?
http://enet.cubik.org
Hi, apologies my website was down earlier (and is quite frequently), I''m hosting it on my own connection at the moment, and play around with it quite a lot.

The signed/unsigned compile warnings aren''t critical, but I admit it''s the kind of thing I should sort out. That library''s only very early code I''ve made in a few weeks for a project, and it''s likely to be extended/improved/bugfixed quite a bit, so if you spot anything serious or have suggestions, drop me a mail. I mainly just put it up to get some comments, and to help anyone else who might be putting something similar together.

Many of the ideas in RFC908 are certainly very useful, and are implemented in some form or another in most reliable UDP protocols. If you can follow the ugly mass of code in my library, many of the features mentioned exist in some form or another, such as send/receive windows, cumulative acknowledgements etc.

Best of luck with your code anyway, it''s certainly a good learning experience If you go multi-threaded, be aware it''s hell to debug.
why reinvent the wheel?

Because at this point I don''t know why the wheel is round, or what width has to do with it. I don''t know if I need a skinny one, a wide one, a tall one, a street tire, or a hoosier racing slick.

Wheels are only best when you know why they are what they are. For that reason I feel I must learn on my own.

-Kyle

This topic is closed to new replies.

Advertisement