So verhindern Sie, dass .NET-Bibliotheken beim Schließen RST-Pakete senden

9

Ich mache ein paar Tests, um etwas seltsames Verhalten in den Bibliotheken (.NET) zu isolieren. Wenn ich die Winsock-API über C ++ verwende und einfach closesocket () anrufe, sehe ich, dass die Windows-Seite das FIN / ACK-Paket sendet und die entfernte Seite ein ACK-Paket zurücksendet. Das würde ich als anmutigen Abschluss bezeichnen. Jedoch, wenn ich in C # programmiere, sehe ich nicht, was ich einen würdevollen Abschluss nennen würde.

In C # öffne ich meinen Socket und dann, wenn ich ihn schließe, sehe ich, dass Windows ein FIN-Paket Nur sendet, wenn er zuerst Socket.Shutdown () aufruft. Unabhängig davon, wenn ich Socket.Close () in C # aufrufen, wird ein RST-Paket gesendet und die Verbindung summarisch gelöscht. Das verwirrt mich, denn nach dem, was ich online gelesen habe, sollte der TCP-Schließvorgang FIN / ACK sein - & gt; ACK (von beiden Seiten eigentlich, aber im Moment bin ich nur mit "meiner" Seite beschäftigt); d.h. es sollte überhaupt kein RST-Paket in der Mischung vorhanden sein. Von dem, was ich gelesen habe, wird anscheinend ein RST-Paket nur gesendet, wenn der Empfänger über den Verbindungszustand unsicher ist und will.

Warum wird dieses RST-Paket bei einem geplanten Herunterfahren in .NET und überhaupt nicht bei einem geplanten Herunterfahren von der Winsock-API gesendet? Gibt es eine Möglichkeit, die Übertragung eines RST-Pakets während eines ordnungsgemäßen Herunterfahrens von .NET zu verhindern?

Falls es wichtig ist, lese ich in beiden Code-Pfaden alle verfügbaren Daten auf dem Socket, bevor ich die entsprechende close () -Methode aufruft.

    
Andrew Falanga 23.08.2011, 17:00
quelle

3 Antworten

3

Lesen des .NET-Dokuments von Socket.Close , das habe ich gefunden:

  

Bei verbindungsorientierten Protokollen wird empfohlen, dass Sie anrufen   Herunterfahren vor dem Aufruf der Close-Methode. Dies gewährleistet, dass alle Daten   wird an der angeschlossenen Steckdose gesendet und empfangen, bevor sie geschlossen wird. Ob   Sie müssen Close aufrufen, ohne zuerst Shutdown aufzurufen, können Sie sicherstellen   Die für die ausgehende Übertragung in die Warteschlange eingereihten Daten werden gesendet, indem Sie die Einstellung   DontLinger Socket-Option auf false und Angabe eines Nicht-Null-Timeouts   Intervall. Close wird dann blockieren, bis diese Daten gesendet werden oder bis die   Das angegebene Zeitlimit läuft ab. Wenn Sie DontLinger auf false setzen und angeben   ein Null-Timeout-Intervall, Schließt die Verbindung und   löscht ausgehende Daten in der Warteschlange automatisch.

was eigentlich Sinn macht. Wenn sich noch Daten im Puffer befinden (Betriebssystem eins) und Sie die Verbindung abbauen oder den Prozess beenden, wird die Verbindung zurückgesetzt (genauere Informationen in den TCP-Spezifikationen).

Wenn RST gesendet wird, schauen Sie sich TCP Guide an.

Meine Vermutung ist, dass es noch einige nicht gesicherte oder in Transit befindliche Daten oder in ausgehende / eingehende Puffer gibt, die die RST auslösen.

    
Boklucius 20.10.2014 19:56
quelle
1

Der folgende Code kann das RST-Paket verhindern. Dies liegt daran, dass 60 Sekunden nach dem Senden eines FIN-Pakets gewartet werden muss.

%Vor%

Schließen Sie die Methodenbeschreibung hier .

    
constdrop 18.09.2015 08:43
quelle
0

Kürzlich ist ein ähnliches Problem aufgetreten, bei dem eine Anwendung POP3 mit einem Exchange-Server gesprochen hat. Als das .NET-Programm beendet wurde, wurde es nicht ordnungsgemäß geschlossen, und Exchange behandelte die POP3-Konversation als "abgebrochen" und rollte sie zurück.

Der Grund dafür ist, dass TCP RST eine "unidirektionale" Nachricht ist - Sie müssen nicht auf eine Antwort warten. Das ist, was .NET sendet (oder vielleicht irgendein Programm, nachdem es beendet wurde.) Eine mögliche Lösung ist, ein wenig zu warten, nachdem der Socket geschlossen wurde und bevor das Programm beendet wird:

%Vor%

Dies funktionierte für das POP3-Problem, das ich bereits erwähnt habe; Die Wartezeit führte dazu, dass die Verbindung ordnungsgemäß beendet wurde und Exchange die Sitzung nicht mehr abbrach.

    
Andomar 23.08.2011 17:14
quelle

Tags und Links