在我的应用程序中,我打开一个原始套接字(LinuxKernel3.8.5),如下所示
说明:
::socket( PF_PACKET, SOCK_RAW, htons((uint16_t)ETH_P_ALL));
一切正常,我可以接收并发送到另一个接口。
但有时
::recvfrom()
在这个套接字上返回1518(1504个有效负载字节+14个eth-hlen)。
当我试图发送这个1518字节的缓冲区时
::send(......)
返回emsgsize(消息太长)。
请注意,在我的网卡接口上是1500,所以我会期望一个最大值。
使用::recvfrom检索的1514字节(有效负载+eth
ethType是0x0800,因此它不是VLAN标记的帧,因此这4个字节的“额外”不是由于VLAN标记
你对此有解释吗?
最佳答案
我的理解是,mtu是特定于连接的,因为它依赖于从源到目标的整个路径,而不仅仅是本地接口。如果您发送到的地址与欺骗数据包的地址不同,那么MTU可能会有所不同,这似乎是很有可能的。
引用Linux man pages:
当pmtu发现启用时,内核会自动跟踪每个目标主机的mtu路径。使用connect(2)将其连接到特定对等机时,可以使用ip_mtu socket选项方便地检索当前已知的路径mtu(例如,在发生emsgsize错误之后)。它可能会随着时间而改变。对于具有许多目的地的无连接套接字,也可以使用错误队列访问给定目的地的新mtu(请参阅ip_recverr)。将为每个传入的MTU更新排队一个新错误。
关于c++ - 原始套接字接收1504个字节(MTU = 1500),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17341553/