如果数据被发送到客户端但客户端正在忙于执行其他操作,那么使用recvfrom()可以读取数据多长时间?
此外,如果在读取第一个数据包之前发送第二个数据包会发生什么情况,第一个数据包是丢失的还是下一个数据包正在等待读取?
(windows - udp)
答案 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%肯定。