recv() gibt 0 aus ohne dass die Verbindung abgebrochen wäre

MarkP

Lieutenant
Registriert
Jan. 2016
Beiträge
639
Ich habe eine relativ kleine Anwendung geschrieben, die aus einem Server- und einem Client-Teil besteht, die untereinander Daten austauschen, beides Win32-Anwendungen, verbunden via wsock32.
Um das folgende Problem zu beheben habe ich vorübergehend mal ALLES aus dem Programm entfernt was stören könnte.

Ich habe die beide Teile, also Server und Client so umkonfiguriert, dass sowohl der Server als auch der Client bei mir auf meinem Heim-PC laufen, sich via "localhost" miteinander verbinden und den Datentransfer habe ich so weit reduziert, dass die nur noch Ping-Pong spielen, also von beiden Seiten alle 10 Sekunden je ein Datenpaket mit 6 Byte senden um einen Timeout am Socket zu verhindern, sprich das Ganze funktioniert auch dann noch wenn mein PC gar nicht am Internet hängt.

Seeeehr unregelmässig, aber doch mit Sicherheit irgendwann, mal nach 10 Minuten, mal erst nach 10 Stunden bricht nun die Verbindung ab.
WSAGetLastError() gibt auf dem Client 10053 aus, was soviel heisst wie Verbindung vom Server beendet.
Am Server gibt es überhaupt keinen Error, sondern da kommt recv() mit einer 0 zurück, was ebenfalls soviel bedeutet wie, Verbindung wurde am anderen Ende beendet.

Im Web gibt es ein paar Leute die dasselbe Problem haben, aber sämtliche Antworten drunter behaupten immer nur, da muss die Verbindung regulär beendet worden sein, ist sie bei mir aber nicht, ganz sicher nicht, denn sonst würde das Ganze nicht einmal 10 Stunden laufen und beim nächsten Mal nur 10 oder 20 Minuten.

Als ganz wilden Testversuch habe ich nu eine Funktion eingebaut, die alle 10 Minuten die Verbindung erneuert, mit Hilfe eines zweiten Ports.
Der Datentransfer wird angehalten, eine neue Socketverbindung auf dem jeweils anderen Port aufgebaut, der alte Socket wird geschlossen, der neue Socket wird den Threads mitgeteilt und dann wird der Datentransfer auf dem neuen Socket inkl. anderem Port fortsetzt, halt auch nur wieder Ping-Pong.
Auf die Art spring die Verbindung alle 10 Minuten zwischen den beiden Ports hin und zurück.
Hilft aber auch nicht, obwohl die Verbindung in diesem Fall nie länger als 10 Minuten steht und der Wechsel vom einem Port zum Anderen prima klappt, bricht immer noch die Verbindung genauso oft ab wie vorher, mal nach 10 Minuten, mal nach mehreren Stunden.

Ich habe das Problem mittlerweile so weit eingekreist, dass IMMER zuerst im recv() am Server die 0 zurück kommt, IMMER ohne WSA Error und der Client erst danach die Verbindung verliert.

Hat Jemand eine Idee dazu?
 
Hm.. Hast du dir den Traffic mal mit WireShark angeschaut?
 
Nein habe ich nicht, aber wozu auch, in der abgespeckten Version jetzt ist da ja gar kein Traffic, der Abbruch findet zu einer Zeit statt wo gar nichts gesendet wird, sprich da sollte der recv() eigentlich warten bis Traffic eingeht, macht er ja auch, mal minutenlang, mal stundenlang korrekt, nur dann auf einmal nicht.
Davon abgesehen zeigt die zurückgegebene 0 ja auch an, dass da kein Traffic war.

Es ist allerdings auch seeeeeehr mühsam da eine Fehlersuche zu betreiben, weil ich halt bei einem Testlauf immer so lange warten muss bis der Fehler auftritt, gerade jetzt im Moment läuft das Ding schon seit 6 Stunden ohne Fehler.
 
Weil man mit WireShark und Co die vollständige Verbindung sieht, inkl. Paketen mit SYN-, ACK-, PSH-, RST- und FIN-Flag, also die komplette Verbindung und nicht nur die empfangenen "Daten". Vielleicht sind mit WireShark bzw. tcpdump so Parallelen zwischen den einzelnen Abbrüchen erkennbar.
 
Ok, stimmt, ist ne Idee, muss ich mal installieren und nachschauen ...... wie lange es dauert bis ich dazu eine Antwort habe kann ich dir aber nicht verspechen.
 
Wie lange es dauert ist mir ehrlich gesagt egal, ich hab ja kein Problem ;)
Eine Garantie, dass du mittels WireShark der Lösung näher kommst, gibt es natürlich nicht, aber es kann einen Hinweis geben woran es liegt.
 
  • Gefällt mir
Reaktionen: Hayda Ministral
Ich merk eh schon, da muss ich mich erstmal einlesen, der scrollt mir die Daten schneller durchs Fenster als ich lesen kann, da brauche ich einen Filter der nur den Traffic auf meinen beiden Ports anzeigt, aber so auf Anhieb habe ich nicht rausgefunden wie ich da hin komme.
Edit: Gefunden, war ja einfach, wenn jetzt nur noch der Fehler auftreten würde.
 
Zuletzt bearbeitet:
Klar scrollt das so schnell durch. Das sind ALLE Pakete, die an der Netzwerkschnittstelle vorbeikommen. Auch wenn die Schnittstelle nicht aktiv genutzt wird, reichen schon ARP und sonstige broadcast-basierte Protokolle aus, um die Liste vollzuspammen ;)

Filter sind aber trivial. Hier ein paar Beispiele:

// Nur Quell-Port filtern
tcp.srcport==123

// Nur Ziel-Port filtern
tcp.dstport==123

// Quell- und Zielport filtern
tcp.port==123

// Verbindung von TCP 123 -> TCP 234 filtern
tcp.srcport==123 && tcp.dstport==234
 
Habs ja gefunden, kann sich also nur noch um Stunden handeln bis der Fehler auftritt, ich geh derweil mal einkaufen.
 
So dala, zuerst mal hat Wireshark mir einen Fehler in meiner Socketswitch-Funktion gezeigt, die hat zwar alle 10 Minuten eine neue Verbindung aufgebaut, aber immer am selbem Port.
Nachdem ich das berichtigt hatte, hat es fast 5 Stunden gedauert, aber dann ist es doch wieder passiert.

Falls du mir sagen kannst, wie ich mehrere Zeilen aus Wireshark auf einmal kopieren und hier einfügen kann mache ich dir einen Auszug, bis dahin kann ich dir sagen, man sieht, dass nach 5 Stunden der letzte Socketswitch um 20402.700090 (was auch immer das für eine Zeit sein soll) stattgefunden hat, der alte Socket wurde um 20402.74222 korrekt geschlossen, der Client hat dann um 20409.256168 auf dem neuen Socket versucht den Ping zu senden, aber der kam nicht an, stattdessen hat um 20409.256189 der Server die Verbindung getrennt.

Das Ganze wohlgemerkt nachdem dieser Socketswitch 5 Stunden lang alle 10 Minuten, also 30x hintereinander funktioniert hat.
Am Switch kann es eh nicht liegen, denn das ist ja nur eine Testfunktion, die ich gestern erst eingebaut habe.
Ohne die Switch-Funktion gäbe es im Wireshark nichts weiter als 5 Stunden lang Ping-Pong zu sehen und dann schliesst der Server ohne ersichtlichen Grund die Verbindung, wobei wie gesagt ..... 5 Stunden waren es diesmal, das nächste Mal kann länger oder auch viel kürzer sein.
 
Zuletzt bearbeitet:
Update: Problem gelöst, allerdings ohne dass ich wüsste woran es gelegen hat.
Statt MinGW32 habe ich das Ganze mal mit MinGW64 gebaut und dabei MinGW64 auf 32bit eingestellt.
Das Problem ist weg, aber fragt mich nicht warum.
 
  • Gefällt mir
Reaktionen: Raijin
Zurück
Oben