Python-Binde-Fehler bei Multicast-Bindung an Windows

Ich muss Multicast in Python-Anwendung verwenden, nach googeln ein bisschen fand ich Snippets von Code, der funktioniert, hier ist es:

# UDP multicast examples, Hugo Vincent, 2005-05-14. import socket import sys import struct def send(data, port=50000, addr='239.192.1.100'): """send(data[, port[, addr]]) - multicasts a UDP datagram.""" # Create the socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # Make the socket multicast-aware, and set TTL. s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 20) # Change TTL (=20) to suit s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 1) # Send the data s.sendto(data, (addr, port)) def recv(port=50000, addr="239.192.1.100", buf_size=1024): """recv([port[, addr[,buf_size]]]) - waits for a datagram and returns the data.""" # Create the socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # Set some options to make it multicast-friendly s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) try: s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) except AttributeError: pass # Some systems don't support SO_REUSEPORT s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 20) # Bind to the port s.bind(('', port)) # Set some more multicast options intf = socket.gethostbyname(socket.gethostname()) s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(intf)) mreq = struct.pack("4sl", socket.inet_aton(addr), socket.INADDR_ANY) s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) # Receive the data, then unregister multicast receive membership, then close the port data, sender_addr = s.recvfrom(buf_size) s.setsockopt(socket.SOL_IP, socket.IP_DROP_MEMBERSHIP, socket.inet_aton(addr) + socket.inet_aton('0.0.0.0')) s.close() return data if __name__=="__main__": if sys.argv[1] == "recv": print recv() else: send("a") 

Ich habe ein Problem mit Bindung und Multicast.

Wie ich verstehe, wenn ich meine Steckdose binden, auf die ich Nachrichten bekomme, in diesem Fall wird es den Verkehr filtern. ('',port) bedeutet, dass ich alle Traffic, die auf diesem Sockel und diesem Port kommt, unabhängig von der Ziel-IP des Pakets (wie 0.0.0.0 ) erhalten, können wir diesen Fall 1 aufrufen.

Auch das funktioniert, wenn ich bin bin bind((addr,port)) . Ich bekomme alle Pakete mit Ziel-IP, die diese Multicast-Gruppe ist (natürlich muss ich auch dieser Multicast-Gruppe beitreten), das ist Fall 2.

Nun, wie ich diese beiden Werke gesagt habe, aber nur auf Linux.

Ich habe mein kleines Programm auf Windows-Maschine ausprobiert, der erste Fall funktioniert aber wenn ich das andere probiere, bekomme ich

  Traceback (most recent call last): File "test.py", line 51, in <module> print recv() File "test.py", line 32, in recv s.bind((addr, port)) File "C:\Python27\lib\socket.py", line 224, in meth return getattr(self._sock,name)(*args) socket.error: [Errno 10049] The requested address is not valid in its context 

Ich bin kein Experte auf Windows-Systemen (ich mache hauptsächlich meine Entwicklung unter Linux), aber ich interessiere mich, warum mein Code mit diesem Fehler nur bei Windows-Systemen ausfällt (ich habe Windows 7 btw).

One Solution collect form web for “Python-Binde-Fehler bei Multicast-Bindung an Windows”

Wie von Carl Cerecke in den Kommentaren des PYMOTW Multicast Artikels erwähnt , wird die Verwendung von socket.INADDR_ANY in Windows an die Standard-Multicast-Adresse binden und wenn Sie mehr als eine Schnittstelle haben Windows hat das Potenzial, die falsche zu wählen.

Um dies zu umgehen, können Sie explizit die Schnittstelle angeben, die Sie Multicast-Nachrichten erhalten möchten:

 group = socket.inet_aton(multicast_group) iface = socket.inet_aton('192.168.1.10') # listen for multicast packets on this interface. sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, group+iface) 

Sie können eine Liste der Schnittstellen mit folgendem erhalten:

 socket.gethostbyname_ex(socket.gethostname()) # ("PCName", [], ["169.254.80.80", "192.168.1.10"]) 

Im obigen Beispiel würden wir wahrscheinlich über die erste 169.254 Link-Local-Adresse überspringen und die gewünschte 192.168.1.10 Adresse auswählen.

 socket.gethostbyname_ex(socket.gethostname())[2][1] # "192.168.1.10" 
  • Wie kann ich die Datenübertragung auf einer Netzwerkschnittstelle in Python überprüfen?
  • Mehrere IP-Adressen zum Testen simulieren
  • Ist es OK, asynchrone Benachrichtigungen vom Server zum Client über dieselbe TCP-Verbindung zu senden?
  • (Sehr) Basis Python Client Socket Beispiel
  • Wie kann ich einen SRV-Datensatz in Python auflösen?
  • Senden eines Reset in TCP / IP Socket-Verbindung
  • Senden von beliebigen Daten mit Twisted
  • Kann SO_REUSEPORT auf Unix Domain Sockets verwendet werden?
  • Python-Bibliothek / Framework zum Schreiben von P2P-Anwendungen
  • Schwierigkeiten mit Pythons Socket.gethostbyaddr ()
  • Warum sollte ich auf einem anderen Server als 127.0.0.1 binden?
  • Python ist die beste Programmiersprache der Welt.