Получение пакетов широковещания в Python

У меня есть следующий код, который отправляет пакет udp, который транслируется в подсети.

from socket import *
s=socket(AF_INET, SOCK_DGRAM)
s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
s.sendto('this is testing',('255.255.255.255',12345))

Следующий код предназначен для приема широковещательного пакета.

from socket import *
s=socket(AF_INET, SOCK_DGRAM)
s.bind(('172.30.102.141',12345))
m=s.recvfrom(1024)
print m[0]

Проблема заключается в том, что он не получает никакого широковещательного пакета. Тем не менее, он успешно получает нормальные пакеты udp, отправленные на этот порт.

Моя машина, очевидно, получала широковещательный пакет, который я тестировал с помощью netcat.

$ netcat -lu -p 12345                                             
this is testing^C

Итак, где именно проблема?

Ответ 1

Попробуйте привязать к адресу по умолчанию:

s.bind(('',12345))

Ответ 2

Я считаю, что решение, изложенное в принятом ответе, решает проблему, но не совсем правильно. Вы не должны использовать обычный IP-интерфейс, а широковещательный IP-адрес, который используется для отправки сообщения. Например, если ifconfig:


inet addr: 10.0.2.2 Bcast: 10.0.2.255 Маска: 255.255.255.0
то сервер должен использовать s.bind(('10.0.2.255', 12345)), а не 10.0.2.2 (в случае OP он должен использовать 255.255.255.255). Причина, по которой принятый ответ работает, заключается в том, что "сообщает серверу принимать пакеты со всех адресов, указывая, что ip-адрес фильтрует его.

" это молот, определяющий правильный широковещательный адрес - скальпель. И во многих случаях, хотя, возможно, и не в OP, важно, чтобы сервер прослушивал только указанный IP-адрес (например, вы хотите принимать запросы только из частной сети - вышеупомянутый код также будет принимать запросы от любой внешней сети), для обеспечения безопасности цели, если ничего другого.

Ответ 3

s=socket(AF_INET, SOCK_DGRAM)
s.bind(('',1234))
while(1):
    m=s.recvfrom(4096)
    print 'len(m)='+str(len(m))
    print 'len(m[0])='+str(len(m[0]))    
    print m[0]

    print 'len(m[1])='+str(len(m[1]))    
    print m[1]