TCP / UDP和以太网MTU碎片
-
18-09-2019 - |
题
我读过的各种网站,在线教程,但我仍然感到困惑。如果消息比IP MTU越大,则send()
返回发送的字节。发生了消息的其余部分是什么?我是否能再次打电话send()
并尝试发送邮件的休息吗?或者是,一些IP层应采取的自动处理?
解决方案
如果使用的是TCP然后呈现给你的接口是一个字节流的。你并不需要担心如何字节流从连接到其它的一端得到。您可以忽略IP层的MTU。事实上,你完全可以忽略IP层。
当你打电话给你的机器将处理为要推到你发送的字节流所需的所有细节上send()
TCP协议栈来电显示从recv()
要求在连接的另一端。
在有一点要记住的是,与TCP你在处理流,这意味着,一个send()
可能导致多个recv()
呼叫和多个呼叫send()
到达可能导致一个recv()
呼叫到达的数据。你必须在这个没有控制权。你正在处理一个字节流和每次调用recv()
可以从1返回任何数目的字节到当前未完成的数目(允许传递到recv()
呼叫足够缓冲器)。
由于评论者要求它;)
在大多数TCP协议栈send()
是最有可能失败,因为TCP堆栈的缓冲区满了,(可能)的TCP窗口也充满了和流送的一切控制在运行,这意味着堆栈无法发送任何更多数据,直到远端的ACK一些数据,它不准备缓冲任何更代表您。我还没有碰到过一个TCP堆栈,将拒绝send()
仅由于MTU的考虑,但我猜有些瘦了嵌入式系统的行为可能这样...
无论如何,如果send()
返回小于您提供它,那么你应该在某个点重新发送的剩余数据的字节数。通常send()
会阻塞等待,直到它可以把所有的数据,如果你设置了插座成非阻塞模式,那么你可能不希望立即重试发送,如果它不能发送的一切,你很可能会结束向上在紧密循环...
这很可能是有用的,为您具体谈谈您所使用的操作系统。
其他提示
如果该分组是太大而通过网络进行传输的ICMP碎片发送提示信令发送器,以减少分组大小和重试。
如果您使用TCP这些都是细节,你应该期待的网络层来照顾你。似乎什么现代IP栈的实际做幕后找出沿路径的最低MTU背后已经有所成了黑色艺术。
WRT UDP你仍然可以期待给出的使用情况UDP堆栈将其分解为你,但实际上它不是理想的..这取决于你的申请有可能通过明确了解路径MTU看到更好的性能。
...上的send()的问题一些堆叠表现不同,但治疗WRT你的代码应该是一样的。比方说你有100个字节发送...发送()返回发送的10个字节。你需要不断的打电话,其余90个字节的发送,直到其全部排挤出丝整封邮件发送。
使用阻塞在Windows平台上发送)插槽(一切后将返回后容易被发送..在其他平台上的Linux ..等你需要不停地发送更多的时候推的数据。