Ich habe ein ziemlich verwirrendes Problem.
Ich benutze eine große C ++ - Bibliothek für die Behandlung eines proprietären Protokolls über UDP unter Windows XP / 7. Während des Programmlaufs wird ein Port überwacht und auf Verbindungen von entfernten Peers gewartet.
Die meiste Zeit funktioniert das gut. Aufgrund einiger Probleme, habe ich beschlossen, einen einfachen Debug-Print direkt nach dem Aufruf von WSARecvFrom
hinzuzufügen (die Win32-Funktion, die in der Bibliothek verwendet wird, um Datagramme von meinem interessanten Socket zu empfangen und zu sagen, welche IP-Adresse) und Port sie kamen aus).
Seltsamerweise habe ich in einigen Fällen entdeckt, dass Pakete auf der Ebene OS fallengelassen werden (dh ich sehe sie in Wireshark, sie haben den richtigen dst-Port, alle Prüfsummen sind korrekt - aber sie erscheinen nie in den Debug-Drucken, die ich in den Code implantiert habe).
Nun, ich bin voll von der Tatsache (Leute neigen dazu, ein bisschen zu oft zu erwähnen), dass "UDP nicht die Lieferung garantiert" - aber das ist nicht relevant, wie die Pakete sind erhalten an der Maschine - ich sehe sie in Wireshark.
Außerdem kenne ich OS-Puffer und das Potenzial, sich zu füllen, aber hier kommt der komische Teil ...
Ich habe einige Nachforschungen angestellt, um herauszufinden, welche Pakete genau fallengelassen werden. Was ich entdeckt habe, ist, dass alle verlorenen Pakete zwei Dinge gemeinsam haben (obwohl einige , aber definitiv nicht am meisten , der Pakete, die nicht sind gelöscht teilen diese auch):
Kann eine dieser beiden Eigenschaften die OS-Puffer beeinflussen und dazu führen, dass Pakete zufällig (oder sogar interessanter - selektiv) gelöscht werden?
Jedes Licht, das auf dieses seltsame Problem geworfen wird, wäre sehr willkommen.
Vielen Dank.
BEARBEITEN (24.10.12):
Ich glaube, ich habe ein wichtiges Detail übersehen. Es scheint, dass die Pakete, die vor der Ankunft gelöscht wurden, etwas anderes gemeinsam haben: Sie (und ich fange an zu glauben, nur sie) werden von "neuen" Peers, dh Peers, die es sind, an den Server gesendet strong> hat nicht versucht, vorher Kontakt aufzunehmen .
Wenn zum Beispiel ein syn-äquivalentes Paket von einem Peer * kommt, den wir noch nie zuvor gesehen haben, wird es von WSARecvFrom
nicht gesehen. Wenn wir jedoch ein syn-äquivalentes Paket an diesen Peer selbst gesendet haben (auch wenn es zu diesem Zeitpunkt nicht geantwortet hat), sendet es jetzt uns ein Syn- Äquivalent, wir werden es sehen.
(*) Ich bin nicht sicher, ob dies ein Peer ist, den wir nicht gesehen haben (zB ip: port) oder nur einen Port , den wir nicht gesehen haben vorher.
Hilft das?
Ist das eine Art WinSock-Option, von der ich noch nie gehört habe? (Wie ich oben sagte, ist der Code nicht meiner, also kann es Socket-Optionen verwenden, die mir nicht bekannt sind)
Nochmals vielen Dank!
Das Betriebssystem verfügt über einen Puffer fester Größe für Daten, die an Ihrem Socket angekommen sind, aber noch nicht von Ihnen gelesen wurden. Wenn dieser Puffer erschöpft ist, fängt er an, Daten zu verwerfen. Die Debug-Protokollierung kann dies verschlimmern, indem die Rate, mit der Daten aus dem Socket abgerufen werden, verzögert wird, was die Wahrscheinlichkeit von Überläufen erhöht.
Wenn dies das Problem ist, könnten Sie zumindest die Instanzen reduzieren, indem Sie einen größeren recv-Puffer anfordern.
Sie können die Größe des Recv-Puffers Ihres Sockets mit
überprüfen %Vor%und Sie können es mit
vergrößern %Vor%Wenn Sie sehen, dass Daten vom Betriebssystem empfangen werden, aber nicht an Ihren Socket-Client gesendet werden, könnten Sie verschiedene Protokollierungsansätze in Betracht ziehen. z.B.
Deaktivieren Sie die Windows-Firewall.
Stimmt das? Wenn dies der Fall ist, können Sie die Firewall wahrscheinlich wieder aktivieren und einfach eine Regel für Ihr Programm hinzufügen.
Das ist meine logischste Annahme, basierend auf dem, was Sie hier in Ihrem Update gesagt haben:
Es scheint, dass die Pakete, die vor der Ankunft gelöscht wurden, etwas anderes teilen gemeinsam: Sie (und ich fange an zu glauben, nur sie) werden geschickt der Server von "neuen" Peers, d. h. Peers, mit denen er nicht in Kontakt gekommen ist vorher.
Bei redhat-linux gab es ein ähnliches Problem. Dies stellt sich als Routing-Problem heraus.
RCA ist wie folgt. 1. Richtig, dass UDP die Zielmaschine erreichen kann (gesehen auf Wireshark). 2. Jetzt wird die Route zur Quelle nicht gefunden, so dass keine Antwort auf dem Wireshark zu sehen ist. 3. Auf einigen Betriebssystemen können Sie das Anfragepaket auf dem Wireshark sehen, aber OS liefert nicht wirklich den Paketsocket (Sie können dieses Socket im netstat-nap sehen). 4. Überprüfen Sie in diesem Fall immer ping (ping -I)
Rgds, Kishor
Tags und Links sockets windows winapi operating-system