Dam*_*mon 16
如果数据被发送到客户端但客户端正在忙于执行其他操作,那么数据可以使用多长时间来读取
recvfrom()?
永远,或根本不,或直到你关闭套接字或读取多个单字节.
原因是:
UDP提供数据报,或者不提供数据报.这听起来像废话,但它正是它的本质.
单个UDP数据报恰好涉及一个或几个"片段",它们是IP数据包(进一步封装在某些"线上"协议中,但这无关紧要).网络堆栈收集数据报的所有片段.如果任何片段的校验和不好,或者任何其他使网络堆栈不满意的事情,那么完整的数据报将被丢弃,你什么也得不到,甚至没有错误.你根本不知道发生了什么.
如果一切顺利,则将完整的数据报放入接收缓冲区.从来没有更少,从来没有更多.如果你试着recvfrom以后,那就是你会得到的.
接收缓冲区显然必须大到足以保存至少一个最大大小的数据报(65535字节),但由于数据报通常不是最大大小,而是1280字节以下(或者如果你愿意,则为1500),它通常可以保持其中相当一部分(在大多数平台上,缓冲区默认为128-256k左右,并且是可配置的).
如果没有足够的空间留在缓冲区,数据包将被丢弃,你会得到什么(当然,你也仍然可以说是已经在缓冲区中的).再说一遍,你甚至都不知道发生了什么.
每次调用时recvfrom,都会从缓冲区中删除一个完整的数据报(重要细节!),并且您可以获得所请求的字节数.这意味着如果你天真地尝试再读几个字节然后再读几个字节,那就不行了.第一次读取将丢弃数据报的其余部分,随后的读取将读取未来某些数据报的第一个字节(并可能阻塞)!
这与TCP的工作方式非常不同.在这里,您实际上可以再次读取几个字节和几个字节,它将起作用,因为网络层模拟数据流.你给它一个垃圾如何工作,因为网络堆栈确保它的工作原理.
此外,如果在读取第一个数据包之前发送第二个数据包会发生什么情况,第一个数据包是丢失的还是下一个数据包等待读取?
你可能想说"收到"而不是"发送".发送和接收具有不同的缓冲区,因此根本不重要.关于在仍然在缓冲区中时接收另一个数据包,请参阅上面的说明.如果缓冲区可以保存第二个数据报,它将存储它,否则它会默默地变为*poof*.
这不会影响缓冲区中已有的任何数据报.
通常,数据将被缓冲,直到读取为止.我想如果你等待足够长的时间,驱动程序完全耗尽空间,它将不得不做一些事情,但假设你的代码合理地工作了一半,那应该不是问题.
典型的网络驱动程序将能够缓冲多个数据包而不会丢失任何数据包.
| 归档时间: |
|
| 查看次数: |
11408 次 |
| 最近记录: |