What should i know about UDP programming?

2019-01-31 04:11发布

问题:

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?

回答1:

"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.



回答2:

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 ).



回答3:

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.



回答4:

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.



回答5:

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.



回答6:

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/



回答7:

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.



回答8:

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.



回答9:

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.



回答10:

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



回答11:

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



回答12:

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.



标签: c++ sockets udp