2012-12-23 27 views

回答

6

這個答案是從 http://books.google.co.il/books?id=9HGUc8AO2xQC&pg=PA31&lpg=PA31&dq#v=onepage&q&f=false (第31頁)採取

s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) 
hostName = #ip here 
Port = 9999 
s.connect((hostName, Port)) 
s.setsockopt(socket.IPPROTO_IP, IN.IP_MTU_DISCOVER, IN.IP_PMTUDISC_DO) 
try: 
    s.send('#' * 1473) 
except socket.error: 
    print 'The message did not make it' 
    option = getattr(IN, 'IP_MTU', 14) 
    print 'MTU:', s.getsockopt(socket.IPPROTO_IP, option) 
else: 
    print 'The big message was sent! Your network supports really big packets!' 
+0

是的,它的工作,但是在udp協議中使用連接是否正確? –

+0

@RahulKatare:是的,它是:「要獲得路徑MTU的初始估計,使用connect(2)將數據報套接字連接到目標地址,並通過使用IP_MTU選項調用getsockopt(2)來檢索MTU。」。 –

+0

什麼是IN? '輸入IN'不起作用 - 使用'IN'搜索並不容易。 –

1

有一個github上,依據提供此功能:

import re 
import socket 
import struct 
import logging 
import subprocess 
from fcntl import ioctl 

SIOCGIFMTU = 0x8921 
SIOCSIFMTU = 0x8922 

log = logging.getLogger(__name__) 

def get_mtu_for_address(ip): 
    routeinfo = subprocess.check_output(['ip', 'route', 'get', ip]) 
    dev = re.search('.*dev (\w+) .*', routeinfo).groups()[0] 
    mtuinfo = subprocess.check_output(['ip', 'link', 'show', dev]) 
    mtu = re.search('.*mtu ([0-9]+) .*', mtuinfo).groups()[0] 
    return int(mtu) 

class Iface: 
    def __init__(self, ifname): 
     self.ifname = ifname 

    def get_mtu(self): 
     '''Use socket ioctl call to get MTU size''' 
     s = socket.socket(type=socket.SOCK_DGRAM) 
     ifr = self.ifname + '\x00'*(32-len(self.ifname)) 
     try: 
      ifs = ioctl(s, SIOCGIFMTU, ifr) 
      mtu = struct.unpack('<H',ifs[16:18])[0] 
     except Exception, s: 
      log.critical('socket ioctl call failed: {0}'.format(s)) 
      raise 

     log.debug('get_mtu: mtu of {0} = {1}'.format(self.ifname, mtu)) 
     self.mtu = mtu 
     return mtu 

    def set_mtu(self, mtu): 
     '''Use socket ioctl call to set MTU size''' 
     s = socket.socket(type=socket.SOCK_DGRAM) 
     ifr = struct.pack('<16sH', self.ifname, mtu) + '\x00'*14 
     try: 
      ifs = ioctl(s, SIOCSIFMTU, ifr) 
      self.mtu = struct.unpack('<H',ifs[16:18])[0] 
     except Exception, s: 
      log.critical('socket ioctl call failed: {0}'.format(s)) 
      raise 

     log.debug('set_mtu: mtu of {0} = {1}'.format(self.ifname, self.mtu)) 

     return self.mtu 


if __name__ == "__main__": 
    import sys 
    logging.basicConfig() 

    mtu = None 
    if len(sys.argv) > 2: 
     dev,mtu = sys.argv[1:] 
    elif len(sys.argv) > 1: 
     dev = sys.argv[1] 
    else: 
     dev = 'eth0' 

    iface = Iface(dev) 
    if mtu is not None: 
     iface.set_mtu(int(mtu)) 

    print dev,'mtu =',iface.get_mtu() 

來源:https://gist.github.com/nzjrs/8934855