Hallo zusammen, ich weiß nicht, ob das nun ein QT-spezielles Problem ist oder ein generelles Netzwerk Problem. In diversen QT-Forum wurde mir bislang nicht geholfen. Ich sitze gerade vor folgendem Problem: Ich habe ein Applikation unter QT, die eine Client-Server-Kommunikation durchführt. Dabei verbindet sich ein Client mit dem Server. Ab dann werden Daten in der Form gesendet, dass der Server etwas sendet und der Client antwortet. Ich habe nur das Problem bei einen ungewollten Verbindungsabbruch (z.B. durch ziehen des Netzwerkkabels). Mein Server ist realisiert durch ein QTcpServer. Sobald sich der Client verbindet, mache ich dahin ein QTcpSocket auf (nextPendingConnection()). Wenn nun Daten zum Client gesendet werden, aber das ACK auf dieses Paket nicht erfolgt, geschieht folgendes: Mein TCP/IP-Stack scheint automatisch Keep-Alive-Messages zu senden. Wenn dann mehrmals keine Antwort kam, bekommt mein QTcpSocket mit, dass es disconnected wurde. Ein nachfolgender Versuch, die Verbindung zu schließen (ein FIN-Packet) schlägt dann auch fehlt. Fatal an der ganzen Geschichte ist, dass ich den TCP/IP-Port, der hier nicht ordentlich geschlossen werden konnte, danach nie wieder benutzen kann. Erst nach einem Neustart des Computers geht es wieder. Hat jemand einen Tipp für mich, was ich versuchen könnte?
Markus_AC schrieb: > Fatal an der ganzen Geschichte ist, dass ich den TCP/IP-Port, der hier > nicht ordentlich geschlossen werden konnte, danach nie wieder benutzen > kann. Erst nach einem Neustart des Computers geht es wieder. Es geht doch um einen PC oder? Welchens betriebssystem? Diesen Verhalten kann überhaupt nicht sein, weil die sockets einer anwendung zugeordnet sind, wenn du die Anwendung zumachst, dann werden auch alles Resourcen freigeben die damit verbunden sind - beleibt bestimmt nichts offen. Was sagt denn Netstat zu diesem Port?
Versuch es mal mit der Socket-Option SO_REUSEADDR (Details siehe "man 7 ip"). Wie man die mit Qt setzt, kann ich Dir allerdings nicht sagen.
Peter II schrieb: > Diesen Verhalten > kann überhaupt nicht sein, weil die sockets einer anwendung zugeordnet > sind, wenn du die Anwendung zumachst, dann werden auch alles Resourcen > freigeben die damit verbunden sind - beleibt bestimmt nichts offen. Nein, ein nicht ordentlich geschlossener serverseitiger Port kann für eine bestimmte Zeit vorerst nicht wieder belegt werden. Damit soll verhindert werden, dass beim Wiederherstellen der Verbindung eventuell noch kursierende Pakete versehentlich einem bereits gestarteten neuen Serverprozess zugeordnet werden, obwohl sie eigentlich ein ICMP destination port unreachable generieren müssten, da sie ja für die nicht ordnungsgemäß beendete Verbindung bestimmt waren. Der entsprechende Port sollte dann im netstat als "TIME_WAIT" markiert sein. Allerdings ist die Wartezeit endlich (was um die 2 Minuten vielleicht, wenn ich mich recht entsinne), und es sollte nicht erst eines Neustarts bedürfen. SO_REUSADDR verhindert diesen TIME_WAIT-Zustand.
Gut, ich werde das mal versuchen. Ich arbeite übrigens sowohl mit Windows- als auch mit einer Linux-Umgebung. Das Verhalten ist bei beiden gleich. Allerdings kommt unter der Linux-Umgebung das disconnect nach den Keep-Alive-Messages nicht (zumindest nicht so schnell wie unter Windows, da ist es etwa 2 Min.).
Hier der Auszug aus dem Wireshark, wenn ich das Netzwerkkabel entferne. Mein Server (192.168.214.251) sendet ein Paket mit Daten der Länge 1, das fehlende ACK der Clients (192.168.214.252) wird mit 5 Keep-Alive-Messages behandelt. Allerdings kann ich nach fast 400 Sekunden immer noch nicht den Port öffnen, obwohl der Default-Wert für TIME_WAIT 240 Sekunden ist. Der vorher geöffnete UDP Port funktioniert jedoch. Leider habe ich bisher keine Möglichkeit gefunden, in QT die Socket-Option SO_REUSEADDR zu setzen. Da es aber auch nach der TIME_WAIT Zeit nicht funktinoiert, muss noch etwas anderes im Argen sein...
Markus_AC schrieb: > Hier der Auszug aus dem Wireshark, wenn ich das Netzwerkkabel entferne. > Mein Server (192.168.214.251) sendet ein Paket mit Daten der Länge 1, > das fehlende ACK der Clients (192.168.214.252) wird mit 5 > Keep-Alive-Messages behandelt. > Allerdings kann ich nach fast 400 Sekunden immer noch nicht den Port > öffnen, obwohl der Default-Wert für TIME_WAIT 240 Sekunden ist. Der > vorher geöffnete UDP Port funktioniert jedoch. > Leider habe ich bisher keine Möglichkeit gefunden, in QT die > Socket-Option SO_REUSEADDR zu setzen. > Da es aber auch nach der TIME_WAIT Zeit nicht funktinoiert, muss noch > etwas anderes im Argen sein... Es handelt sich hier nicht um keepalives sondern um simple Paketwiederholungen. Schliesst du den Socket nach dem Fehler ? Es ist kein FIN oder RST zu sehen. Erzeugt du eine völlig neuen Socket oder versuchst du auf dem altem Socket weiter zu senden ? Welche Socket bezogenden Calls spuckt strace aus ? Welche Sockets in welchem State werden zu verschiedenden Zeitpunkten von netstat -anp ausgespuckt ? P.S.: Bitte Traces in Zukunft als *.pcap hochladen.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.