UDP 数据包在套接字上停留多长时间?
如果数据发送到客户端,但客户端正忙于执行其他操作,那么使用 recvfrom() 可以读取数据多长时间?
另外,如果在读取第一个数据包之前发送第二个数据包,会发生什么情况,第一个数据包是否丢失,而下一个数据包坐在那里等待读取?
(Windows - UDP)
If data is sent to the client but the client is busy executing something else, how long will the data be available to read using recvfrom()?
Also, what happens if a second packet is sent before the first one is read, is the first one lost and the next one sitting there wating to be read?
(windows - udp)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
永远,或者根本不,或者直到您关闭套接字或读取一个字节。
原因是:
UDP 传送数据报,或者不传送数据报。这听起来像是废话,但事实确实如此。
单个 UDP 数据报与一个或多个“片段”相关,这些“片段”是 IP 数据包(进一步封装在某种“在线”协议中,但这并不重要)。网络堆栈收集数据报的所有片段。如果任何片段的校验和不好,或者任何其他使网络堆栈不满意的事情,整个数据报将被丢弃,并且您什么也得不到,甚至没有错误。你根本不知道发生了什么。
如果一切顺利,完整的数据报将被放入接收缓冲区。绝不能少,也绝不能多。如果您稍后尝试
recvfrom
,这就是您将得到的结果。接收缓冲区显然必须足够大,以容纳至少一个最大大小的数据报(65535 字节),但由于通常数据报不会是最大大小,而是低于 1280 字节(或 1500,如果你愿意),它通常可以容纳其中相当多(在大多数平台上,缓冲区默认约为 128-256k,并且是可配置的)。
如果缓冲区中没有足够的空间,则数据报将被丢弃,并且您什么也得不到(嗯,您仍然得到缓冲区中已经存在的数据报) 。再说一次,你甚至不知道发生了什么事。
每次调用
recvfrom
时,都会从缓冲区中删除完整的数据报(重要细节!),并且您可以获得所请求的字节数。这意味着,如果您天真地尝试读取几个字节,然后再次读取几个字节,它将无法工作。第一次读取将丢弃数据报的其余部分,随后的读取将读取一些未来数据报的第一个字节(并且可能会阻塞)!这与 TCP 的工作方式非常不同。这里你实际上可以读几个字节,再读几个字节,它就会正常工作,因为网络层模拟了一个数据流。你根本不在乎它是如何工作的,因为网络堆栈确保它能工作。
您可能想说“已收到”而不是“已发送”。发送和接收有不同的缓冲区,所以这根本不重要。关于当一个数据包仍在缓冲区中时接收另一个数据包,请参阅上面的解释。如果缓冲区可以容纳第二个数据报,它将存储它,否则它会默默地* poof *。
这不会影响缓冲区中已有的任何数据报。
Forever, or not at all, or until you close the socket or read as much as a single byte.
The reason for that is:
UDP delivers datagrams, or it doesn't. This sounds like nonsense, but it is exactly what it is.
A single UDP datagram relates to either exactly one or several "fragments", which are IP packets (further encapsulated in some "on the wire" protocol, but that doesn't matter). The network stack collects all fragments for a datagram. If the checksum on any of the fragments is not good, or any other thing that makes the network stack unhappy, the complete datagram is discarded, and you get nothing, not even an error. You simply don't know anything happened.
If all goes well, a complete datagram is placed into the receive buffer. Never anything less, and never anything more. If you try to
recvfrom
later, that is what you'll get.The receive buffer is obviously necessarily large enough to hold at least one max-size datagram (65535 bytes), but since usually datagrams will not be maximum size, but rather something below 1280 bytes (or 1500 if you will), it can usually hold quite a few of them (on most platforms, the buffer defaults to something around 128-256k, and is configurable).
If there is not enough room left in the buffer, the datagram is discarded, and you get nothing (well, you do still get the ones that are already in the buffer). Again, you don't even know something happened.
Each time you call
recvfrom
, a complete datagram is removed from the buffer (important detail!), and you get up to the number of bytes that you requested. Which means if you naively try read a few bytes and then a few bytes again, it just won't work. The first read will discard the rest of the datagram, and the subsequent ones read the first bytes of some future datagrams (and possibly block)!This is very different from how TCP works. Here you can actually read a few bytes and a few bytes again, and it will just work, because the network layer simulates a data stream. You give a crap how it works, because the network stack makes sure it works.
You probably meant to say "received" rather than "sent". Send and receive have different buffers, so that would not matter at all. About receiving another packet while one is still in the buffer, see the above explanation. If the buffer can hold the second datagram, it will store it, otherwise it silently goes * poof *.
This does not affect any datagrams already in the buffer.
通常,数据将被缓冲直到被读取。我想如果你等待足够长的时间,驱动程序完全耗尽空间,它就必须做一些事情,但假设你的代码可以合理地工作一半,那应该不是问题。
典型的网络驱动程序将能够缓冲多个数据包而不会丢失任何数据包。
Normally, the data will be buffered until it's read. I suppose if you wait long enough that the driver completely runs out of space, it'll have to do something, but assuming your code works halfway reasonably, that shouldn't be a problem.
A typical network driver will be able to buffer a number of packets without losing any.
这取决于操作系统,在Windows中,我相信每个UDP套接字的默认值是8012,这可以通过setsockopt()来提高 Winsock 文档 因此,只要缓冲区未满,数据就会保留在那里,直到套接字关闭或被关闭。 读。
如果缓冲区有空间,则它们都被存储,如果没有,则其中之一被丢弃。我相信它是最新的,但我不是 100% 确定。
This depends on the OS, in windows, I believe the default for each UDP socket is 8012, this can be raised with setsockopt() Winsock Documentation So, as long as the buffer isn't full, the data will stay there until the socket is closed or it is read.
If the buffer has room, they are both stored, if not, one of them gets discarded. I believe its the newest one but I'm not 100% Sure.