Я пытаюсь создать сокет 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')
Последовательно, только первое, третье и пятое сообщение (message 1
, message 3
и message 5
) пройдёт и будет напечатан на сервере.Второе, четвертое и шестое сообщения не отображаются на выходе сервера, и вместо этого клиент получает исключение:
>>> c.send('message 2')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
socket.error: [Errno 111] Connection refused
Выполнение этого в Wireshark показывает, что он получает ICMP-ответ для «Назначение недоступно»».Я смог воспроизвести это на 3 разных машинах (хотя все работают под Linux).Я что-то пропустил?Это ожидаемое поведение для UDP, чтобы последовательно отбрасывать пакеты, так как протоколы, использующие его, должны быть терпимы к потере пакетов?Тем не менее, почему пакеты будут отбрасываться при отправке на локальный интерфейс?
Привязка сервера к 127.0.0.1
вместо 0.0.0.0
дает тот же результат.