Goal I am writing a python windows application that needs to search for available network devices using ssdp. The search will be used to get the IP addresses for specific device types to set up a connection. Problem We were getting very inconsistent ssdp search results. Sometimes it works, sometimes it fails. Using Wireshark and Device Sniffer (from Meshcommander UPnP tools), we discovered that when it fails, the ssdp M-SEARCH is getting sent to 127.0.0.1, so it never reaches the network. There appears to be no rhyme or reason for when it works or fails. I am confident this is specific to windows, as the same code works on Mac without issue. Code that works intermittently: import socket import struct import time local_ip = '192.168.20.48' ssdp_addr = "239.255.255.250" ssdp_port = 1900 searchterm = 'ssdp:all' m_msg = f"""\ M-SEARCH * HTTP/1.1\r\n\ Host: {ssdp_addr}:{ssdp_port}\r\n\ Man: "ssdp:discover"\r\n\ ST: {searchterm}\r\n\ MX: 2\r\n\r\n""".encode("utf-8") if __name__ == "__main__": # Method 1, occassionally works. Most of the time sends to 127.0.0.1ort sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 5) sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) sock.settimeout(5) sock.sendto(m_msg, (ssdp_addr, ssdp_port)) # Sometimes works, sometimes doesn't... # If send worked, this will receive the response. But, if send is routed to 127.0.0.1, # nothing is received (which is expected given it is localhost) tLim = time.time() + 6 while time.time() < tLim: try: data, addr = sock.recvfrom(4096) print(f"Received from {addr}: {data}") except socket.timeout: break sock.close() This issue also occurs with the ssdpy library on PyPi, which is not surprising as the source of the library is similar to the above implementation. Attempted Solution I have experimented with every type of windows configuration I can think of (Firewall settings, services, permissions, switching networks...) to no avail. After searching online I found a method where the sent M-Search message no longer gets routed to 127.0.0.1, but I am unable to receive the response from the device! With wireshark, I can see the response is sent by the device, but the code wont read it. Although the implementation WILL find the random ssdp traffic that is occurring at the same time on the network. import socket import struct import time local_ip = '192.168.20.48' ssdp_addr = "239.255.255.250" ssdp_port = 1900 searchterm = 'ssdp:all' m_msg = f"""\ M-SEARCH * HTTP/1.1\r\n\ Host: {ssdp_addr}:{ssdp_port}\r\n\ Man: "ssdp:discover"\r\n\ ST: {searchterm}\r\n\ MX: 2\r\n\r\n""".encode("utf-8") if __name__ == "__main__": # Method 2 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind((local_ip, ssdp_port)) group = socket.inet_aton(ssdp_addr) mreq = struct.pack('4s4s', group, socket.inet_aton(local_ip)) sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) sock.settimeout(5) ret = sock.sendto(m_msg, (ssdp_addr, ssdp_port)) # CODE to listen for SSDP responses. This finds unrelated network upnp notifies, but # does not get the response from the device. I can see the response from the device is # being sent with wireshark tLim = time.time() + 6 while time.time() < tLim: try: data, addr = sock.recvfrom(4096) print(f"Received from {addr}: {data}") except socket.timeout: break sock.close() With this method, Wireshark shows the M-SEARCH with Source/Destination = 192.168.20.48 / 239.255.255.250 and the response from the device Source/Destination = 192.168.30.82 / 192.168.20.48 Where 192.168.20.48 = PC local IP, and 192.168.30.82 = device local IP. Help I am wondering if there are changes I can make to either of these methods to make them work consistently. The first method works part of the time, some of the time. The second method half works all the time. I am open to using a modified version of either of these methods, or a totally new one if I am completely on the wrong track. Continue reading...