UDP数据包在套接字上停留多长时间?

T.T*_*.T. 15 c sockets windows winapi winsock

如果数据被发送到客户端但客户端正在忙于执行其他操作,那么使用recvfrom()读取数据可以使用多长时间?

此外,如果在读取第一个数据包之前发送第二个数据包会发生什么情况,第一个数据包是丢失的还是下一个数据包正在等待读取?

(windows - udp)

Dam*_*mon 16

如果数据被发送到客户端但客户端正在忙于执行其他操作,那么数据可以使用多长时间来读取recvfrom()

永远,或根本不,或直到你关闭套接字或读取多个单字节.

原因是:
UDP提供数据报,或者不提供数据报.这听起来像废话,但它正是它的本质.

单个UDP数据报恰好涉及一个或几个"片段",它们是IP数据包(进一步封装在某些"线上"协议中,但这无关紧要).网络堆栈收集数据报的所有片段.如果任何片段的校验和不好,或者任何其他使网络堆栈不满意的事情,那么完整的数据报将被丢弃,你什么也得不到,甚至没有错误.你根本不知道发生了什么.

如果一切顺利,则将完整的数据报放入接收缓冲区.从来没有更少,从来没有更多.如果你试着recvfrom以后,那就是你会得到的.

接收缓冲区显然必须大到足以保存至少一个最大大小的数据报(65535字节),但由于数据报通常不是最大大小,而是1280字节以下(或者如果你愿意,则为1500),它通常可以保持其中相当一部分(在大多数平台上,缓冲区默认为128-256k左右,并且是可配置的).
如果没有足够的空间留在缓冲区,数据包将被丢弃,你会得到什么(当然,你仍然可以说是已经在缓冲区中的).再说一遍,你甚至都不知道发生了什么.

每次调用时recvfrom,都会从缓冲区中删除一个完整的数据报(重要细节!),并且您可以获得所请求的字节数.这意味着如果你天真地尝试再读几个字节然后再读几个字节,那就不行了.第一次读取将丢弃数据报的其余部分,随后的读取将读取未来某些数据报的第一个字节(并可能阻塞)!

这与TCP的工作方式非常不同.在这里,您实际上可以再次读取几个字节和几个字节,它将起作用,因为网络层模拟数据流.你给它一个垃圾如何工作,因为网络堆栈确保它的工作原理.

此外,如果在读取第一个数据包之前发送第二个数据包会发生什么情况,第一个数据包是丢失的还是下一个数据包等待读取?

你可能想说"收到"而不是"发送".发送和接收具有不同的缓冲区,因此根本不重要.关于在仍然在缓冲区中时接收另一个数据包,请参阅上面的说明.如果缓冲区可以保存第二个数据报,它将存储它,否则它会默默地变为*poof*.
这不会影响缓冲区中已有的任何数据报.


Jer*_*fin 8

通常,数据将被缓冲,直到读取为止.我想如果你等待足够长的时间,驱动程序完全耗尽空间,它将不得不做一些事情,但假设你的代码合理地工作了一半,那应该不是问题.

典型的网络驱动程序将能够缓冲多个数据包而不会丢失任何数据包.

  • 它将主要填充套接字缓冲区,而不是(仅)驱动程序.它将保留在套接字缓冲区中,直到您读取它或进程退出.一旦套接字缓冲区已满,就会丢弃到达的新数据包. (5认同)

8bi*_*ide 7

如果数据被发送到客户端但客户端正在忙于执行其他操作,那么使用recvfrom()读取数据可以使用多长时间?

这取决于操作系统,在Windows中,我相信每个UDP套接字的默认值是8012,这可以通过setsockopt()Winsock文档引发,所以,只要缓冲区未满,数据就会保留在那里直到套接字已关闭或已被阅读.

此外,如果在读取第一个数据包之前发送第二个数据包会发生什么情况,第一个数据包是丢失的还是下一个数据包正在等待读取?

如果缓冲区有空间,则它们都被存储,如果没有,则其中一个被丢弃.我相信它是最新的,但我不是100%肯定.