tags:

views:

1108

answers:

13

I don't mean how to connect to a socket. What should I know about UDP programming?

  • Do I need to worry about bad data in my socket?
  • I should assume if I send 200bytes I may get 120 and 60 bytes separately?
  • Should I worry about another connection sending me bad data on the same port?
  • If data doesnt arrive typically how long may I (typically) not see data for (250ms? 1 second? 1.75sec?)

What do I really need to know?

+14  A: 

"i should assume if i send 200bytes i may get 120 and 60bytes separately?"

When you're sending UDP datagrams your read size will equal your write size. This is because UDP is a datagram protocol, vs TCP's stream protocol. However, you can only write data up to the size of the MTU before the packet could be fragmented or dropped by a router. For general internet use, the safe MTU is 576 bytes including headers.

"i should worry about another connection sending me bad data on the same port?"

You don't have a connection, you have a port. You will receive any data sent to that port, regardless of where it's from. It's up to you to determine if it's from the right address.

If data doesnt arrive typically how long may i (typically) not see data for (250ms? 1 second? 1.75sec?)

Data can be lost forever, data can be delayed, and data can arrive out of order. If any of those things bother you, use TCP. Writing a reliable protocol on top of UDP is a very non trivial task and there is no reason to do so for almost all applications.

Don Neufeld
I am writing some game code so packet loss is welcomed. I want to know how long should i except to not receive any data (so i con determine how may frames back i should wait)
acidzombie24
I've written a number of commercial games, and as a rule, just because it's a game doesn't mean packet loss is acceptable. We typically wait at least 30 seconds before establishing that a user is completely link dead when using UDP.
Don Neufeld
Packet loss shouldn't be welcome. Instead you should be concentrating on not sending much data. As Don hints, packet loss might mean that the connection is lost - maybe it's high loss, or there is a burst of latency. Use of UDP for games is a well researched area. Knowing that you are writing a game, writing a reliable wrapper on UDP _might_ be applicable in this situation. But Don's warning should be heeded - it is non trivial. Search on the net - lots of good info out there in proper use of UDP in games.
Mark
+1  A: 

And don't assume that if you send a packet it got there.

Joshua
+3  A: 

The big thing to know when attempting to use UDP is:

Your packets might not all make it over the line, which means there is going to be possible data corruption.

If you're working on an application where 100% of the data needs to arrive reliably to provide functionality, use TCP. If you're working on an application where some loss is allowable (streaming media, etc.) then go for UDP but don't expect everything to get from one of the pipe to the other intact.

Justin Niessner
+7  A: 

Your packet may not get there.

Your packet may get there twice or even more often.

Your packets may not be in order.

You have a size limitation on your packets imposed by the underlying network layers. The packet size may be quite small (possibly 576 bytes).

None of this says "don't use UDP". However you should be aware of all the above and think about what recovery options you may want to take.

Brian Agnew
I remember hearing about not on order, but receiving the same packet TWICE!?! Thats something i would never think about.
acidzombie24
Set it and forget it.
Joe Philllips
+1  A: 

If there is a packet size limitation imposed by some router along the way, your UDP packets could be silently truncated to that size.

sean riley
Does this mean i may get half a packet on my side?
acidzombie24
Also, if you datagram is fragmented by one router, other downstream routers might refuse to carry fragmented datagrams, resulting in complete data loss.
benc
+4  A: 

UDP is a connectionless protocol. Sending data over UDP can get to the receiver, but can also get lost during transmission. UDP is ideal for things like broadcasting and streaming audio or video (i.e. a dropped packet is never a problem in those situations.) So if you need to ensure your data gets to the other side, stick with TCP.

UDP has less overhead than TCP and is therefore faster. (TCP needs to build a connection first and also checks data packets for data corruption which takes time.)

Fragmented UDP packets (i.e. packets bigger than about half a Kb) will probably be dropped by routers, so split your data into small chuncks before sending it over. (In some cases, the OS can take care of that.) Note that it is allways a packet that might make it, or not. Half packets aren't processed.

Latency over long distances can be quite big. If you want to do retransmission of data, I would go with something like 5 to 10 times the agerage latency time over the current connection. (You can measure the latency by sending and receiving a few packets.)

Hope this helps.

Jeroen Landheer
Great stuff. Especially the make it or not, another poster made me worry about partial packets.What do you mean retransmission of data? Wait latency time (lets say 60ms) *5 to 10 before considering it failed?
acidzombie24
What you can do when establishing a session is measure the latency time. Send for example 5 small UDP packets to the destination and let it answer back with 4 packets, measure the average time it takes to make the roundtrip and take that as a base for the rest of the session. If you have long running sessions you might want to repeat this process at some point.
Jeroen Landheer
+5  A: 

Fragmentation and reassembly happens at the IP level, so you need not worry about that (Wikipedia). (This means that you won't receive split or truncated packets).

UDP packets have a checksum for the data and the header, so receiving bogus data is unlikely, but possible. Lost or duplicate packets are also possible. You should check your data in any case anyway.

There's no congestion control, so you may wish to consider that, if you plan on clogging the tubes with a lot of UDP packets.

TrayMan
It should also be emphasized that fragmentation (assuming that is working, sometimes it is going to work) is particularly a concern when mixed in an environment with noticeable packet loss, because the lost of any fragment means the datagram will not reassemble on the destinations IP stack. In other words, when the path from two UDP sockets is lossy, fragmentation doubles the effective rate of failure for datagrams.
benc
Quite true. I should've worded it better. You do need to worry about the possibility of exceeding the MTU of any segment on the packet's path, causing fragmentation, but any packets that get through are delivered as whole.
TrayMan
A: 

Two things:

1) You may or may not received what was sent

2) Whatever you receive may not be in the same order it was sent.

Dan
+1  A: 

In addition to don.neufeld's recommendation to use TCP.

For most applications TCP is easier to implement. If you need to maintain packet boundaries in a TCP stream, a good way is to transmit a two byte header before the data to delimit the messages. The header should contain the message length. At the receiving end just read two bytes and evaluate the value. Then just wait until you have received that many bytes. You then have a complete message and are ready to receive the next 2-byte header.

This gives you some of the benefit of UDP without the hassle of lost data, out-of-order packet arrival etc.

Dave Turvey
i dont need all the data to get to the other side. its also for a game like prototype
acidzombie24
Lost data is only one of many unexpected conditions when using UDP...
benc
+2  A: 

One way to look at the difference between applications appropriate for UDP vs. TCP is that TCP is good when data delivery is "better late than never", UDP is good when data delivery is "better never than late".

Another aspect is that the stateless, best-effort nature of most UDP-based applications can make scalability a bit easier to achieve. Also note that UDP can be multicast while TCP can't.

Lance Richardson
+7  A: 

Should I worry about another connection sending me bad data on the same port?

Yes you should worry about it. Any application can send data to your open UDP port at any time. One of the big uses of UDP is many to one style communications where you multiplex communications with several peers on a single port using the addressed passed back during the recvfrom to differentiate between peers.

However, if you want to avoid this and only accept packets from a single peer you can actually call connect on your UDP socket. This cause the IP stack to reject packets coming from any host:port combo ( socket ) other than the one you want to talk to.

A second advantage of calling connect on your UDP socket is that in many OS's it gives a significant speed / latency improvement. When you call sendto on an unconnected UDP socket the OS actually temporarily connects the socket, sends your data and then disconnects the socket adding significant overhead.

A third advantage of using connected UDP sockets is it allows you to receive ICMP error messages back to your application, such as routing or host unknown due to a crash. If the UDP socket isn't connected the OS won't know where to deliver ICMP error messages from the network to and will silently discard them, potentially leading to your app hanging while waiting for a response from a crashed host ( or waiting for your select to time out ).

Robert S. Barnes
Great info. I never considered connect
acidzombie24
+2  A: 

I won't follow suit with the other people who answered this, they all seem to push you toward TCP, and that's not for gaming at all, except maybe for login/chat info. Let's go in order:

Do I need to worry about bad data in my socket?

Yes. Even though UDP contains an extremely simple checksum for routers and such, it is not 100% efficient. You can add your own checksum device, but most of the time UDP is used when reliability is already not an issue, so data that doesn't conform should just be dropped.

I should assume if I send 200bytes I may get 120 and 60 bytes separately?

No, UDP is direct data write and read. However, if the data is too large, some routers will truncate and you lose part of the data permanently. Some have said roughly 576 bytes with header, I personally wouldn't use more than 256 bytes (nice round log2 number).

Should I worry about another connection sending me bad data on the same port?

UDP listens for any data from any computer on a port, so on this sense yes. Also note that UDP is a primitive and a raw format can be used to fake the sender, so you should use some sort of "key" in order for the listener to verify the sender against their IP.

If data doesnt arrive typically how long may I (typically) not see data for (250ms? 1 second? 1.75sec?)

Data sent on UDP is usually disposable, so if you don't receive data, then it can easily be ignored...however, sometimes you want "semi-reliable" but you don't want 'ordered reliable' like TCP uses, 1 second is a good estimate of a drop. You can number your packets on a rotation and write your own ACK communication. When a packet is received, it records the number and sends back a bitfield letting the sender know which packets it received. You can read this unfinished document for more information (although unfinished, it still yields valiable info):

http://gafferongames.com/networking-for-game-programmers/

sabriath
excellent answer. I'm very glad you replied.
acidzombie24
A: 

My server use UDP. It sends 900bytes/1ms to my program automatically after being acquired. I'm using socket API in Windows. I try calling setsockopt function to set the bigger buffer:

setsockopt(SockNum, SOL_SOCKET, SO_RCVBUF, SockBuffer(1), 1048576)

but I still lost data. I think that I need make a FIFO buffer for UDP. Should I do that and how I can do?

kheo
you can post questions yourself.
acidzombie24
I'm sorry, I think my job has something same in this post. Thanks!
kheo