closesocket() von 300 TCP Verbindungen: Nicht alle RST ACK werden vom Server empfangen



  • Hallo!

    Folgendes habe ich beobachtet: Wenn der Client 300 TCP Verbindungen zum Server aufbaut, und dann 300 closesocket() beim Clienten aufgerufen werden, sendet der Client 300 RST ACK Pakete, der Server empfängt aber nicht alle (bei ~200 Verbindungen geht es noch)!
    Client & Server sind eigene Programme, überprüft mit Wireshark.
    Die restlichen Verbindungen (einmal waren es 14, dann 63) bleiben am Server als "ESTABLISHED" zurück, auch wenn ich minutenlang warte. Clientseitig sind keine Verbindungen mehr offen (überprüft mit tcpview).
    Habe das Serverprogramm übrigens auf 3 verschiedenen Computern getestet (Server 2003/32, Server 2008/64 und Server 2012/64, überall das gleiche). Ab ca. 250 Verbindungen werden eben einige RST ACK Pakete nicht empfangen. Wenn ich anstatt closesocket() ein shutdown SD_SEND mache und kurz warte, werden alle Verbindungen normal beendet.
    Woran könnte das liegen? Stellt TCP bei einem forcible shutdown keine Garantien? Sind 300 Pakete auf einmal schon so viel, dass das Netzwerk einige dropped?!

    Danke!



  • Hmm, habe gerade von einer "tcp rst attack" gelesen, vielleicht blockt irgendein Segment ja ab einer gewissen Anzahl (ISP vermutlich), ist eigentlich das plausibelste. Ich meine, mal eben so 300 resets auf einmal... auch nicht ganz üblich, nehme ich an.



  • Ok hab mal eben ein Sleep(1) zw. den closesocket() calls eingebaut, und siehe da, alle 1000 Verbindungen werden am Server geschlossen...



  • Graceful shutdown.

    An application should not assume that any outstanding I/O operations on a socket will all be guaranteed to completed when closesocket returns. The closesocket function will initiate cancellation on the outstanding I/O operations, but that does not mean that an application will receive I/O completion for these I/O operations by the time the closesocket function returns.

    if( graceful == false )
    	{
    	    // force the subsequent closesocket to be abortative.
    		LINGER  lingerStruct;
    
    		lingerStruct.l_onoff = 1;
    		lingerStruct.l_linger = 0;
    		setsockopt(m_bsocket, IPPROTO_TCP, SO_LINGER, reinterpret_cast<char *> (&lingerStruct), static_cast<int> (sizeof(lingerStruct)) );
    

    }



  • @EOP
    Ich sehe nicht was das mit der Frage des OP zu tun haben soll.
    Er schreibt ja

    Die restlichen Verbindungen (einmal waren es 14, dann 63) bleiben am Server als "ESTABLISHED" zurück, auch wenn ich minutenlang warte. Clientseitig sind keine Verbindungen mehr offen (überprüft mit tcpview).

    In deinem Zitat geht's ja nur darum, dass closesocket nicht wartet bis alle ausständigen IOs abgeschlossen wurden. Also dass man damit rechnen muss dass ein Completion-Callback o.ä. aufgerufen wird nachdem closesocket schon zurückgekommen ist. Und natürlich damit dass IOs einfach gecancelt/verworfen werden.



  • An application should not assume that any outstanding I/O operations on a socket will all be guaranteed to completed when closesocket returns.

    Was ist daran unverständlich?

    Konnte den code leider nicht so schnell adden wie du geantwortet hast.



  • Das frag ich mich auch, aber du verstehst es anscheinend nicht 😕
    Wie entnimmst du daraus bitte dass ein RST Paket in so einem Fall nicht verschickt werden könnte?



  • Mann, würg das Ding einfach mit "graceful == false" ab wenn's sein muss.
    No need to understand the inner workings.



  • Kann er ja probieren. Würde mich aber sehr wundern wenn das hilft.


Anmelden zum Antworten