Python-raw-socket lauschen auf UDP-Pakete; nur die Hälfte der empfangenen Pakete

Ich versuche zu erstellen raw socket in Python hört sich das für UDP-Pakete nur:

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)

Dieser muss als root ausgeführt werden, und erstellt einen raw socket auf port 1337, das hört sich für UDP-Pakete und gibt Sie aus, wenn Sie empfangen werden; da auch keine Probleme.

Nun machen wir eine kleine client zu testen, ob dies funktioniert:

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')

Konsequent, nur die erste, Dritte und fünfte Botschaft (message 1, message 3 und message 5) durch und gedruckt werden, in der server-Ausgabe. Der zweiten, vierten und sechsten Nachrichten nicht zeigen, bis auf der server-Ausgabe, und stattdessen bekommt der Kunde eine Ausnahme:

>>> c.send('message 2')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
socket.error: [Errno 111] Connection refused

Laufen diese in Wireshark zeigt, dass es immer eine ICMP-Antwort für "Ziel nicht erreichbar". Ich war in der Lage reproduzieren diese auf 3 verschiedenen Rechnern (alle mit Linux allerdings). Bin ich etwas fehlt? Ist dieses erwartete Verhalten für das UDP-Protokoll konsequent Pakete verwerfen, da die Protokolle, die das benutzen sollen tolerant gegenüber Paketverlust? Auch so, warum sollte Pakete werden gelöscht, wenn gesendet wird auf der lokalen Benutzeroberfläche?

Bindung der server 127.0.0.1 statt 0.0.0.0 hat das gleiche Ergebnis.

  • Manchmal geschehen merkwürdige Dinge mit der Meldung stack. Der ethernet-adapter in diesem Fall verwendet die loopback, aber immer noch die Pakete "phsically" gehen noch auf die Karte und dann interpretiert werden, indem der Fahrer wie Sie, um die message queue. nur einige der Forschung, Punkte zu helfen.
  • FlavorScape ich bekomme die Fehlermeldung jedes zweite Paket, das scheint viel zu regelmäßig, um ein Netzwerk-Fehler...
  • Ja, es passiert jedes der zwei Pakete, was bedeutet, dass, wenn Sie senden 2*n - Pakete, alle Pakete, die von der form 2*i+1 wird nicht durchkommen. Ich glaube nicht, dass diese werden können Paketverlust, da diese alle auf der lokalen Schnittstelle.
  • Ich vermute, es liegt daran, dass man mit RAW <-> DGRAM oder etwas ähnliches.
  • Bestätigt. Wenn Sie eine socket.SOCK_DGRAM server-Seite, es funktioniert wie erwartet.
  • Ja, in der Tat, aber wie die Frage sagt, brauche ich eine raw-socket (um das UDP Paket-header).
  • Der Header enthält vier Dinge: src, die Sie aus der recvfrom() Gegenzug dst, das ist der port, den du hörst auf, die Länge des Pakets an, die werden nie größer als 2^16, die Sie bekommen können aus dem Paket Lesen aus dem Netzwerk, und die Prüfsumme, die behandelt wird durch den kernel. Was Sie tun müssen?
  • Ich sollte erwähnt haben, die IP-Paket-header hier auch, aber ich erkannte das zu spät, um den Kommentar Bearbeiten, sorry. Ich brauche das, um zu wissen, was mit dem Paket; es wird weitergeleitet durch iptables

Schreibe einen Kommentar