Мне нужно написать код, в котором мне нужно отправлять данные по протоколу udp в python. Мне нужно установить размер пакета равным значению MTU сети. Есть ли способ, которым я могу определить значение MTU сети, написав код на python?
Как найти значение mtu сети через код (в python)?
Ответы (3)
Этот ответ был взят с сайта 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!'
person
hillel_guy
schedule
23.12.2012
Да, это сработало, но правильно ли использовать подключение по протоколу udp?
- person Rahul Katare; 24.12.2012
@RahulKatare: Да, это так: чтобы получить начальную оценку MTU пути, подключите сокет дейтаграммы к адресу назначения, используя connect (2), и получите MTU, вызвав getockopt (2) с параметром IP_MTU.
- person Matt Joiner; 19.06.2013
Что такое
IN
? import IN
не работает - гуглить IN
непросто.
- person Isaac Turner; 09.11.2017
Ah -
IN
определяет сетевые константы конкретной платформы. Он был удален из Python 3.6 python.readthedocs. .io/en/latest/whatsnew/
- person Isaac Turner; 09.11.2017
Существует github-gist, обеспечивающий эту функциональность:
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
person
Humoyun Ahmad
schedule
27.12.2016
У меня не работает в Python 3.7. Вызов
ioctl
в get_mtu
вызывает: OSError: [Errno 6] Device not configured
- person Damon Maria; 15.04.2021
Принятый ответ не работал у меня в Python 3.7. Я получаю: OSError: [Errno 6] Device not configured
Но теперь в psutil
это встроено.
import psutil
print(psutil.net_if_stats())
Результат:
{
'lo0': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=0, mtu=16384),
'en0': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=0, mtu=1500),
...
}
person
Damon Maria
schedule
14.04.2021