Я пытаюсь создать сокет rawв Python, который прослушивает только UDP-пакеты:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_UDP)
s.bind(('0.0.0.0', 1337))
while True:
print s.recvfrom(65535)
Это нужно запустить от имени пользователя root и создать необработанный сокет на порту 1337 который прослушивает пакеты UDP и распечатывает их всякий раз, когда они получены; там нет проблем.
Теперь давайте создадим небольшой клиент, чтобы проверить, работает ли это:
import socket
c = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
c.connect(('127.0.0.1', 1337))
c.send('message 1')
c.send('message 2')
c.send('message 3')
c.send('message 4')
c.send('message 5')
c.send('message 6')
Последовательно, только первое, третье и пятое сообщение ( сообщение 1
, сообщение 3
и сообщение 5
) пройдет и будет напечатано на выходе сервера.Второе, четвертое и шестое сообщения не отображаются на выходе сервера, и вместо этого клиент получает исключение:
>>> c.send('message 2')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
socket.error: [Errno 111] Connection refused
Выполнение этого в Wireshark показывает, что он получает ответ ICMP для «Destination unreachable». Я смог воспроизвести это на 3 разных машинах (хотя все они работают под управлением Linux). Я что-то упускаю? Является ли это ожидаемым поведением для UDP, чтобы последовательно отбрасывать пакеты, поскольку протоколы, использующие его, должны быть терпимы к потере пакетов? Тем не менее, почему пакеты будут отбрасываться при отправке через локальный интерфейс?
Привязка сервера к 127.0.0.1
вместо 0.0.0.0
дает тот же результат.