![]() |
|
How to write safe UDP socket programs? |
Michael Faerber
Member #4,800
July 2004
![]() |
I have heard that TCP network sockets were slower than UDP and that you had to use UDP for network broadcasts, so I thought about switching to UDP in my network library. Problem is, that UDP seems to have no guarantee that a message is really sent. So I wanted to ask you if you knew a system to guarantee that complete messages are sent and received. -- |
HoHo
Member #4,534
April 2004
![]() |
you write your own wrapper protocol around UDP. __________ |
Michael Faerber
Member #4,800
July 2004
![]() |
Thanks for your link, but desperately, the headline says it all: Low level Nonsense and Network Theory! I would be happy about a code snippet implementing an existant protocol wrapper. -- |
Frank Drebin
Member #2,987
December 2002
![]() |
can't you use both tcp/udp at the same time - so tcp for the important packages and udp for the rest |
HoHo
Member #4,534
April 2004
![]() |
Guess what I found after googling for "reliable udp code"' Well, technically I didn't find it via google, the third link it gave was broken but searching reliable udp from codeproject gave that. __________ |
Michael Faerber
Member #4,800
July 2004
![]() |
Frank: My network library's design is much more like UDP (although it uses TCP), so I think it's just logic that I will use UDP from now. But I could make abstract classes, which would allow me to use both systems. HoHo: Thanks for this link, I've downloaded the source and will have a further look at it! EDIT: I looked at the source code and it seems to take some time to understand it. Does nobody have a small source file? -- |
A J
Member #3,025
December 2002
![]() |
HawkNL, has reliable (TCP), unreleiable(UDP) ,and something called reliable packets (UDP with reliablity code). ___________________________ |
gering
Member #4,101
December 2003
![]() |
RakNet uses UDP with reliablity code. __________________________________________________________ |
Michael Faerber
Member #4,800
July 2004
![]() |
I know of these libraries, but the basic question (the question of life -- |
HoHo
Member #4,534
April 2004
![]() |
Quote: How can the peers (clients and servers) know, whether packets have been sent correctly or not? With UDP they can't. __________ |
Michael Faerber
Member #4,800
July 2004
![]() |
What? Before, you said I should write a wrapper protocol around UDP to guarantee that packages are sent completely. To send complete packages, I must know whether the package has arrived. So if I don't know if a package has been received, guaranteed package sending is impossible!! -- |
HoHo
Member #4,534
April 2004
![]() |
example: You put and ID(serial number) into each packet. [edit] __________ |
Frank Drebin
Member #2,987
December 2002
![]() |
and that's why i think it's a good idea to use tcp (at least) too. |
Michael Faerber
Member #4,800
July 2004
![]() |
But what advantages has TCP over UDP (when you have successfully implemented an UDP wrapper)? -- |
Frank Drebin
Member #2,987
December 2002
![]() |
it is reliable... |
HoHo
Member #4,534
April 2004
![]() |
But UDP has much shorter latency [url http://www.flipcode.com/articles/network_part07.shtml] Quote: TCP vs. UDP (continued) TCP is a simple and effective way of transmitting data. For making sure that your client and server can talk to each other it is very good. However, it carries with it a lot of overhead and extra network lag so once you feel you are ready you should make the jump to UDP. The big problems you will face with UDP include: # You won't have an individual socket for each client. In fact FD_ACCEPT will never be called. There won't be any clear notice that the client now sending you data wants to join the game unless you make the client say as much. While switching to UDP will get you a signifigant speed boost, there are a few more tricks you can try.
__________ |
BAF
Member #2,981
December 2002
![]() |
Use enet (I tried and recommend it) or raknet (heard it was good) ? |
orz
Member #565
August 2000
|
It seems like this is coming up a lot lately. UDP and TCP have the same latency, if you adjust the TCP settings for low latency. If you use default settings, TCP can have up to twice the latency of UDP. Note that this comparison assumes the network has no packet loss... if there's packet loss the comparison is more complicated, and TCP may fare worse. TCP has NO advantage over UDP + a good wrapper, except that TCP is a standard. TCP is more or less THE standard implementation of UDP + wrapper. The advantage of reimplementing the wrapper yourself is that you get to optimize the wrapper for your particular purposes, or concievably even do a better job than the TCP designers did. |
amarillion
Member #940
January 2001
![]() |
-- |
Michael Faerber
Member #4,800
July 2004
![]() |
How to adjust settings for TCP to have lower latency? -- |
gillius
Member #119
April 2000
|
Some notes: orz is right in his implication that any general wrapper for reliable UDP is not beneficial. TCP guarantees delivery and ordering, and it does this with a lossy datagram-oriented protocol (IP). UDP is not much more than adding the concept of ports to IP and is pretty much raw IP, which TCP is built upon. The benefit to using UDP reliablity layers is if you want some but not all of the features given by TCP:
</li> If you are unconditionally implementing all of the five features above with a reliable UDP layer, then there won't be an advantage over TCP except that the TCP layer in your OS is probably more tested than your code Gillius |
orz
Member #565
August 2000
|
Adjusting TCP for low-latency stuff: The most important thing is to disable packet-combining (aka Nagle algorithm). If you don't do this, it wont send any data until either all previous packets have been acknoledged or the send buffer contains a lot of data. int tmp = 1; setsockopt ( sock, IPPROTO_TCP, TCP_NODELAY, (const char *)&tmp, sizeof(tmp)); I think it's also a good idea to reduce the size of the send buffer if your programs bandwidth usage varies based upon how much is available. If you're writting a game that uses a fixed amount of bandwidth then this is not useful. It's done like this: tmp = 2048; setsockopt ( sock, SOL_SOCKET, SO_SNDBUF, (const char *)&tmp, sizeof(tmp)); On some operating systems it may also be a good idea to adjust "low water thresholds", but I'm not sure about that, they can't be adjusted on windows, and I think they default to good values on linux, so it's pretty much irrelevant. |
Michael Faerber
Member #4,800
July 2004
![]() |
orz, many thanks for this function! This will probably save me a lot of time! I just have one question: If I disable the Nagle algorithm, I probably won't have to reduce the send buffer, because I send everything immediately anyway, don't I? -- |
orz
Member #565
August 2000
|
If the Nagle algorithm is disabled, it won't delay anything for the purpose of improving bandwidth efficiency. But it will still delay things for the purpose of throttling the connection down to the available bandwidth. i.e. If you send some data, and the send buffers are small, then the socket will then be not-ready-to-send, as in, if you select with only that socket in the write set, and no read or except set, then select will block if there's a timeout or return 0 if there's not, and remove that socket from the set. This is the desired behavior in low-latency variable-bandwidth games. If you are confident that available bandwidth is large compared to used bandwidth, you don't need to worry about that. If you have no ability to vary the bandwidth usage for your game, then there's not much point in worrying about it, any clients without enough bandwidth are doomed anyway. But if your games uses variable bandwidth, you need to know when to stop sending, otherwise the buffers will fill up with older data that may be optional anyway, and newer data that's mandatory will get delayed waiting for the older data to finish. Or at least, that's my understanding. |
|