Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么不是';";不要断章取义;国旗被禁用了?_Python_Sockets_Python 2.7 - Fatal编程技术网

Python 为什么不是';";不要断章取义;国旗被禁用了?

Python 为什么不是';";不要断章取义;国旗被禁用了?,python,sockets,python-2.7,Python,Sockets,Python 2.7,我正在尝试使用setsockopt()对udp数据包碎片设置不同的IP_MTU_DISCOVER值的效果,并发现(从man页面的IP(7))我需要将其值设置为IP_PMTUDISC\u WANT或IP_PMTUDISC\u DONT以关闭“不碎片”标志。但是,当我尝试发送数据包时,我收到的socket.error:[Errno 90]消息太长 import IN, socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) hostn

我正在尝试使用
setsockopt()
对udp数据包碎片设置不同的
IP_MTU_DISCOVER
值的效果,并发现(从
man
页面的
IP(7)
)我需要将其值设置为
IP_PMTUDISC\u WANT
IP_PMTUDISC\u DONT
以关闭“不碎片”标志。但是,当我尝试发送数据包时,我收到的
socket.error:[Errno 90]消息太长

import IN, socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

hostname = 'localhost'
s.connect((hostname, 1060))

s.setsockopt(socket.IPPROTO_IP, IN.IP_MTU_DISCOVER, IN.IP_PMTUDISC_DONT)
mtu = s.getsockopt(socket.IPPROTO_IP, IN.IP_MTU)

print 'MTU:', mtu
s.send('.' * (mtu + 1))
print 'Big packet sent'

谢谢

让我们首先回顾一下PMTU是如何为UDP工作的

  • IP端点以给定的MTU开始,通常是其直接连接链路的MTU
  • 发送数据包时,端点始终设置DF位
  • 如果中转路由器决定在不分割数据包的情况下无法发送数据包,它将返回一个
    ICMP目的地不可到达
    数据包,错误代码为4和下一跳MTU
  • IP端点接收无法访问的ICMP并调整其PMTU
  • IP端点决定如何处理原始数据包(重传、信号应用层等)
  • 这里需要特别注意的是,PMTU不会自动发生。在您(应用程序)开始发送实际数据之前,没有内置的探测数据包可以找到MTU

    因此Linux使用以下标志来控制(数据报):

    • IP_PMTUDISC_WANT
      执行上述PMTU。如果应用程序发送的数据包对于已知的MTU来说太大,套接字层将对其进行分段。传出数据包(包括片段)将设置DF位
    • IP\u PMTUDISC\u DONT
      不要执行PMTU发现
    • IP\u PMTUDISC\u DO
      DO PMTU发现。如果应用程序发送的数据包对于已知MTU来说太大,则向应用程序发送错误
    • IP_PMTUDISC_PROBE
      将DF位设置为执行PMTU发现,但忽略当前学习的MTU。因此,如果应用程序发送的数据包太大,它将尝试发送出去。这有助于不时发送探测器,查看PMTU是否增加
    现在需要注意的是,
    IP\u PMTUDISC\u DONT
    没有指定如果数据包实际大于您当前的MTU(即您的直接链接的MTU),该怎么办。因此,最有可能的情况是,它将这个选择留给实际必须发送数据包的接口。由于DF位没有发送,大多数接口实际上应该对数据包进行分段。但是,您使用的是link-local接口,它通常是一个功能稍差的软件接口。在您的发行版上,这可能不支持碎片,因此会发送错误。这很有意义,从我的机器上获取以下输出:

    In [6]: s.getsockopt(socket.IPPROTO_IP, 14) #14 = IP_MTU, just wasn't in my python lib.
    Out[6]: 16436
    

    这表明链路本地接口的MTU在网络方面是相当大的,那么为什么要从支持碎片开始呢。也就是说,在我的系统上,这实际上运行得很好。

    当我将
    IP\u PMTUDISC\u DONT
    替换为
    IP\u PMTUDISC\u WANT
    时,会出现相同的错误,为什么?它应该会把包裹弄碎,对吗?你看过我的全部答案了吗?最后,我指定了独立于该设置的碎片可能出现的问题。