Python функция recvfrom () не возвращает никаких данных - PullRequest
1 голос
/ 09 июля 2020

Я хотел бы сделать предисловие, что я новичок в сети и все еще работаю над своими python навыками, поэтому go мне легко.

Я начал работать над проектом сканирования сети и играл с несколько протоколов, чтобы попытаться найти то, что лучше всего подходит для моих целей. SSDP кажется мне лучшим, поэтому я играл с маленьким универсальным скриптом plug and play, который я нашел, чтобы попробовать и проверить, как все работает в моей сети.

import socket  
import sys

dst = "239.255.255.250"  
st = "upnp:rootdevice"  
msg = [  
    'M-SEARCH * HTTP/1.1',
    'Host:239.255.255.250:1900',
    'Man:"ssdp:discover"',
    'MX:1',
    'ST:%s' % (st,),
    '']
    
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
s.bind((socket.gethostbyname(socket.gethostname()), 0))
print(s.getsockname())
s.settimeout(60)
byte_data = '\r\n'.join(msg) 
s.sendto(bytes(byte_data, 'utf-8'), (dst, 1900))
while True:  
    try:
        data, addr = s.recvfrom(32*1024)
    except socket.timeout:
        print("timeout has occurred")
        break
    print (f"$ {addr}\n{data}")
s.close() 

По какой-то причине это всегда для меня и никогда не отображает никаких данных. После исследования с помощью WireShark я вижу, что мой компьютер отправляет запросы, а устройства отправляют ответы на мой компьютер. Кто-нибудь знает, почему это может происходить (ОС - windows 10). Я скажу, что я увеличивал время ожидания в несколько раз до больших значений, но по-прежнему ничего не проходит.

1 Ответ

0 голосов
/ 28 августа 2020

Как указано в комментариях, в заголовке запроса M-SEARCH должна быть дополнительная пустая строка, поэтому.

import socket
import sys

dst = "239.255.255.250"
st = "upnp:rootdevice"
msg = [
    'M-SEARCH * HTTP/1.1',
    'Host:239.255.255.250:1900',
    'Man:"ssdp:discover"',
    'MX:1',
    'ST:%s' % (st,),
    '',
    '']

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
s.bind((socket.gethostbyname(socket.gethostname()), 0))
print(s.getsockname())
s.settimeout(2)
byte_data = '\r\n'.join(msg)
s.sendto(bytes(byte_data, 'utf-8'), (dst, 1900))
while True:
    try:
        data, addr = s.recvfrom(32 * 1024)
    except socket.timeout:
        print("timeout has occurred")
        break
    print(f"$ {addr}\n{data}")
s.close()

Теперь это работает. Кроме того, с заголовком SSDP MX, установленным на 1, бессмысленно устанавливать тайм-аут на 60 - любое устройство, отвечающее на запрос, ДОЛЖНО отвечать в течение MX секунд или не отвечать вообще.

* 1005 система с единым сетевым интерфейсом. Но в многосетевой системе вам нужно будет отправлять запрос на каждый интерфейс, привязав сокет к этому интерфейсу, иначе некоторые устройства UPNP могут быть недоступны.
...