关于 UDP 编程我应该了解什么?
我的意思不是如何连接到套接字。 关于 UDP 编程我应该了解什么?
- 我需要担心套接字中的错误数据吗?
- 我应该假设如果我发送 200 字节,我可能会分别得到 120 和 60 字节?
- 我是否应该担心另一个连接在同一端口上向我发送错误数据?
- 如果数据通常没有到达,我(通常)在多长时间内看不到数据(250 毫秒?1 秒?1.75 秒?)
我真正需要知道什么?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
当您发送 UDP 数据报时,您的读取大小将等于您的写入大小。这是因为 UDP 是一种数据报协议,而不是 TCP 的流但是,在数据包可能被路由器分段或丢弃之前,您只能写入 MTU 大小的数据。对于一般 Internet 使用,安全 MTU 为 576 字节(包括标头)。
您没有连接,您有一个端口。您将收到发送到该端口的任何数据,无论它来自哪里。由您来确定它是否来自正确的地址。
数据可能会永远丢失,数据可能会延迟,数据可能会乱序到达。 如果这些事情困扰您,请使用 TCP。在 UDP 之上编写可靠的协议是一项非常重要的任务,并且没有理由对几乎所有应用程序都这样做。
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.
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.
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.
是的,你应该担心它。 任何应用程序都可以随时向您开放的 UDP 端口发送数据。 UDP 的一大用途是多对一风格的通信,您可以使用在
recvfrom
期间传回的地址来与单个端口上的多个对等方进行多路复用通信,以区分对等方。但是,如果您想避免这种情况并且只接受来自单个对等点的数据包,您实际上可以在 UDP 套接字上调用
connect
。 这会导致 IP 堆栈拒绝来自任何主机:端口组合(套接字)的数据包,而不是您要与之通信的数据包。在 UDP 套接字上调用
connect
的第二个优点是,在许多操作系统中,它可以显着提高速度/延迟。 当您在未连接的 UDP 套接字上调用sendto
时,操作系统实际上会临时连接该套接字,发送数据,然后断开该套接字,从而增加了显着的开销。使用连接的 UDP 套接字的第三个优点是它允许您接收返回到应用程序的 ICMP 错误消息,例如由于崩溃而导致路由或主机未知。 如果 UDP 套接字未连接,操作系统将不知道将 ICMP 错误消息从网络传递到何处,并会默默地丢弃它们,可能会导致您的应用程序在等待崩溃主机的响应时挂起(或等待您的应用程序)选择超时)。
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 callsendto
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 ).
您的包裹可能无法到达那里。
您的包裹可能会两次甚至更频繁地到达那里。
您的包裹可能不整齐。
底层网络层对数据包的大小有限制。 数据包大小可能非常小(可能576字节)。
这些都没有说“不要使用 UDP”。 但是,您应该了解上述所有内容,并考虑您可能想要采取哪些恢复选项。
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.
碎片和重组发生在 IP 级别,因此您不必担心 (Wikipedia)。 (这意味着您不会收到分割或截断的数据包)。
UDP 数据包具有数据和标头的校验和,因此不太可能接收到伪造数据,但也有可能。 丢失或重复的数据包也是可能的。 无论如何,您都应该检查您的数据。
没有拥塞控制,因此如果您打算用大量 UDP 数据包堵塞管道,您可能需要考虑这一点。
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.
UDP 是一种无连接协议。 通过UDP发送数据可以到达接收者,但也可能在传输过程中丢失。 UDP 非常适合广播和流式音频或视频(即在这些情况下丢包永远不会成为问题)。因此,如果您需要确保数据到达另一端,请坚持使用 TCP。
UDP 的开销比 TCP 少,因此速度更快。 (TCP 需要首先建立连接,并检查数据包是否有数据损坏,这需要时间。)
分段的 UDP 数据包(即大于约半 Kb 的数据包)可能会被路由器丢弃,因此在发送之前将数据分成小块结束了。 (在某些情况下,操作系统可以处理这个问题。)请注意,它始终是一个可能成功或失败的数据包。 不处理一半数据包。
长距离的延迟可能会很大。 如果你想重新传输数据,我会选择当前连接的平均延迟时间的 5 到 10 倍。 (您可以通过发送和接收几个数据包来测量延迟。)
希望这会有所帮助。
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.
我不会效仿其他回答这个问题的人,他们似乎都在推动你走向 TCP,而这根本不是为了游戏,除了登录/聊天信息。 我们按顺序来吧:
是的。 尽管 UDP 包含非常简单的路由器校验和等,但它并不是 100% 有效。 您可以添加自己的校验和设备,但大多数情况下,当可靠性已经不是问题时,会使用 UDP,因此不符合要求的数据应该被丢弃。
不,UDP是直接数据写入和读取。 但是,如果数据太大,某些路由器会截断,您将永久丢失部分数据。 有人说大约 576 字节带头,我个人不会使用超过 256 字节(很好的圆形 log2 数字)。
UDP 侦听端口上任何计算机的任何数据,因此从这个意义上来说是的。 另请注意,UDP 是一种原语,原始格式可用于伪造发送者,因此您应该使用某种“密钥”,以便侦听器根据其 IP 验证发送者。
通过 UDP 发送的数据通常是一次性的,因此如果您没有收到数据,那么它很容易被忽略。 ..然而,有时你想要“半可靠”,但你不想要像 TCP 使用的“有序可靠”,1 秒是对下降的一个很好的估计。 您可以轮流对数据包进行编号并编写您自己的 ACK 通信。 当接收到数据包时,它会记录编号并发回一个位字段,让发送者知道它收到了哪些数据包。 您可以阅读此未完成的文档以获取更多信息(虽然未完成,但它仍然提供了有效的信息):
http ://gafferongames.com/networking-for-game-programmers/
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:
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.
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).
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.
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/
尝试使用 UDP 时需要了解的重要一点是:
您的数据包可能无法全部通过线路,这意味着可能会出现数据损坏。
如果您正在开发的应用程序需要 100% 的数据可靠地到达才能提供功能,请使用 TCP。 如果您正在开发一个允许某些丢失的应用程序(流媒体等),那么请选择 UDP,但不要期望所有内容都能完好无损地从一个管道传输到另一个管道。
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.
查看适合 UDP 与 TCP 的应用程序之间的差异的一种方法是,当数据传输“迟到总比不好”时,TCP 是好的,而当数据传输“不迟到总比不好”时,UDP 是好的。
另一方面是,大多数基于 UDP 的应用程序的无状态、尽力而为的性质可以使可扩展性更容易实现。 另请注意,UDP 可以进行多播,而 TCP 则不能。
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.
除了 don.neufeld 建议使用 TCP 之外。
对于大多数应用程序来说,TCP 更容易实现。 如果需要维护 TCP 流中的数据包边界,一个好方法是在数据之前传输两个字节标头来分隔消息。 标头应包含消息长度。 在接收端只需读取两个字节并评估该值。 然后等待,直到收到那么多字节。 然后您就获得了完整的消息并准备好接收下一个 2 字节标头。
这为您提供了 UDP 的一些好处,而不会出现数据丢失、数据包乱序到达等问题。
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.
并且不要假设如果您发送一个数据包它就会到达那里。
And don't assume that if you send a packet it got there.
如果沿途某个路由器施加了数据包大小限制,您的 UDP 数据包可能会被悄悄截断为该大小。
If there is a packet size limitation imposed by some router along the way, your UDP packets could be silently truncated to that size.
有两件事:
1) 您可能收到也可能没有收到发送的内容
2) 您收到的内容可能与发送的顺序不同。
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.