设置IP标头的标志字段

时间:2009-06-23 23:33:22

标签: python sockets

我有一个简单的Python脚本,它使用套接字模块发送UDP数据包。该脚本在我的Windows机器上运行正常,但在我的Ubuntu Linux PC上,它发送的数据包略有不同。在Windows上,IP标头中的标志字段为零,但在Linux上使用相同的代码创建了一个标志字段设置为4的数据包。我想修改我的脚本,使其在Windows和Linux上具有一致的行为。

是否有控制套接字模块中flags字段的方法?或者,这是我必须在Linux中更改的设置吗?

3 个答案:

答案 0 :(得分:6)

这是我最终选择的路线。我按照S.SashaN在D.Shwley回答的评论中发布的链接,了解了为什么在Linux的UDP数据包中设置“不分段”位的原因。事实证明它与PMTU发现有关。简而言之,您可以使用套接字对象中的setsockopts函数清除Python中UDP包的碎片位。

import socket
IP_MTU_DISCOVER   = 10
IP_PMTUDISC_DONT  =  0  # Never send DF frames.
IP_PMTUDISC_WANT  =  1  # Use per route hints.
IP_PMTUDISC_DO    =  2  # Always DF.
IP_PMTUDISC_PROBE =  3  # Ignore dst pmtu.
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("10.0.0.1", 8000))
s.send("Hello World!") # DF bit is set in this packet
s.setsockopt(socket.SOL_IP, IP_MTU_DISCOVER, IP_PMTUDISC_DONT)
s.send("Hello World!") # DF bit is cleared in this packet

答案 1 :(得分:2)

我猜测标志字段实际上设置为2 = b010而不是4 - 等于4的标志是无效的IP数据包。请记住,标志是IP Header中的3位值。我希望看到UDP数据报的标志值为2,这意味着“不要碎片化”。

至于你的问题,我不相信有一种方法可以直接设置IP标志而不必使用raw sockets。我不担心,因为大多数应用程序都没有充分的理由直接使用IP甚至是UDP / TCP头。

答案 2 :(得分:1)

construct可以做这个工作吗?