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

时间:2011-10-20 23:58:06

标签: c windows winapi sockets winsock

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

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

(windows - udp)

3 个答案:

答案 0 :(得分:15)

  

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

永远,或者根本不是,或者直到你关闭套接字或读取多个字节为止。

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

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

如果一切顺利,完整数据报将被放入接收缓冲区。从来没有更少,从来没有更多。如果您稍后尝试recvfrom,那就是您将获得的。

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

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

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

  

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

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

答案 1 :(得分:7)

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

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

答案 2 :(得分:7)

  

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

这取决于操作系统,在Windows中,我相信每个UDP套接字的默认值是8012,这可以用setsockopt()Winsock Documentation来提升所以,只要缓冲区未满,数据将一直呆在那里,直到插座关闭或读取。

  

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

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