C++ 原始套接字的数据包碎片

C++ 原始套接字的数据包碎片,c++,sockets,udp,fragmentation,C++,Sockets,Udp,Fragmentation,如果我使用原始套接字发送大小为3000字节的UDP数据包,我是否需要在代码中自己处理数据包碎片,或者原始套接字是否应该处理类似于DGRAM套接字的碎片?不,数据包碎片是在较低级别处理的。你应该清楚地看到你在包里放了什么,然后再出来。也就是说,UDP保证了消息边界。底层协议IP仍然处理碎片。我认为,只要您没有设置(不分段)位,您就应该可以了。根据您的系统,这可以以完全不同的方式处理。例如,在Linux上,如果您尝试发送大于(已知)路径MTU的内容,您可以要求较低层处理路径MTU发现,并给出错误(E

如果我使用原始套接字发送大小为3000字节的UDP数据包,我是否需要在代码中自己处理数据包碎片,或者原始套接字是否应该处理类似于DGRAM套接字的碎片?

不,数据包碎片是在较低级别处理的。你应该清楚地看到你在包里放了什么,然后再出来。也就是说,UDP保证了消息边界。

底层协议IP仍然处理碎片。我认为,只要您没有设置(不分段)位,您就应该可以了。

根据您的系统,这可以以完全不同的方式处理。例如,在Linux上,如果您尝试发送大于(已知)路径MTU的内容,您可以要求较低层处理路径MTU发现,并给出错误(EMSGSIZE)

你所说的原始套接字有多“原始”?其他系统可能只允许您控制DF位(或者您可能自己构建大部分IP头),在这种情况下,行为也将取决于此


通常,如果您使用DF set进行传输,您通常可以选择查看用户空间中的错误,或者让主机上的较低级别处理PMTU发现并停止发送太大的内容。如果您没有设置DF,那么您(可能)会看到路由器沿着路径出现适当的碎片。

如果您使用UDP,那么您并不是真正发送RAW。RAW根本就没有IP,在这种情况下,您必须自己处理碎片

通过UDP,您可以获得IP的分段支持,这对于冲突应该最小的短途网络来说已经足够好了。将两个系统之间的链接设为专用子网,这根本不是问题


TCP通过UDP(除其他外)给您带来的好处是,如果某个片段丢失或丢失,堆栈只需重新发送一个片段。使用UDP时,如果发生这种情况,则必须丢弃整个消息。不过,这会带来开销,对于大多数现代网络来说,你可能会接受这种权衡。

对于Linux,答案是肯定的。如果你看一看Linux,原始套接字不会重新组装。

如果我没有弄错,并且我怀疑我对这个问题的看法是正确的,那么你确实需要担心数据包丢失等问题,UDP是一个尽最大努力的协议。数据包(如果接收)很好-但是,不能保证保留顺序。显然,如果您是send/resp/send/resp,这不是一个问题,但如果您是流媒体,这将是一个问题。UDP的问题是,一旦你实现了所有的内务管理,你只希望你一开始就做了TCP。通常情况下,当您不担心数据包丢失时,情况并非如此。您能澄清一下在这种情况下,您所说的raw到底是什么意思吗?您正在编写原始以太网帧、原始IP数据包吗?你在什么系统上做这个?一些系统提供某种“半n半”套接字…我的意思是通过IP_原始套接字发送IP数据包。下面是后续问题。同意其他答案缺少“原始”的观点。尽管不同意您的结论,但有些系统具有“原始IP”套接字,您仍然可以在其中指定IP头的源地址和目标地址,但可以自己编写数据包的其余部分。在这种情况下,将有一个IP头(一半由应用程序构造,一半由较低级别管理),它将有一个正常的DF位。@awoodland-有趣。我的经验主要是写自己的书堆。如果用户正在处理填写IP数据包,我想他们还必须处理将IP片段组装成消息。我认为问题只是关于传输,因为它要求发送!问题是,在这个例子中,“raw”是什么意思还不是很清楚。我已经添加了关于如何处理碎片的后续问题。谢谢你的回答。