TCP-Half-Close erst nach dem Leeren der ausstehenden Bytes weiterleiten
EOF in einem TCP-Proxy behandeln, ohne gepufferte Daten zu verwerfen oder die Antwort in der anderen Richtung abzuschneiden.
Der Client ist mit dem Senden fertig, der Proxy sieht EOF, und die Antwort verschwindet. Beide Proxy-Sockets sofort zu schließen kann genau diese Reihenfolge auslösen. In einem TCP-Relay bedeutet ein geordnetes Ende in einer Richtung nicht, dass die andere Richtung beendet ist.
Betrachten Sie einen Client, der eine Anfrage sendet, seine Sendeseite herunterfährt und auf die Antwort wartet:
client -- request, then FIN --> proxy --> service
client <-------- reply ------- proxy <-- service
Der Proxy hat zwei TCP-Verbindungen und zwei sich unabhängig bewegende Byteströme. Er muss die Anzeige des Eingabeendes weiterreichen, nachdem er die ihr vorangehenden Bytes weitergereicht hat.
Warteschlange leeren, bevor EOF weitergeleitet wird
Bei einem Empfang ungleich null auf einem TCP-Stream zeigt die Rückgabe von null ein geordnetes Ende dieses eingehenden Streams an. Markieren Sie diese Leserichtung als beendet. Warten Sie nicht mehr auf weitere Eingaben von ihr, behalten Sie aber Bytes, die bereits für den gegenüberliegenden Socket in der Warteschlange stehen.
Sobald die Warteschlange vom Client zum Dienst geleert ist, rufen Sie shutdown(service_socket, SHUT_WR) auf einem POSIX-Socket auf. Das beendet die weitere Übertragung zum Dienst und lässt die Richtung vom Dienst zum Client verfügbar. Wenn der Dienst seine Antwort beendet hat, wenden Sie die gespiegelte Operation an, nachdem die Antwortwarteschlange geleert ist.
Das Schließen der Deskriptoren gehört an den Punkt, an dem beide Richtungen und ihre ausstehenden Puffer fertig sind oder an dem ein Fehler oder Abbruch eine Beendigung erfordert. Halten Sie ein begrenztes Timeout für einen Peer bereit, der seine verbleibende Hälfte nie abschließt.
Bereitschaft ist eine Einladung zum Lesen
Ein lesbarer Socket kann Daten oder einen EOF-Zustand haben. Rufen Sie recv auf und interpretieren Sie das Ergebnis. Positive Werte sind zu übertragende Bytes; null ist das richtungsbezogene Ende. Bei einem nicht blockierenden Socket bedeutet EAGAIN oder EWOULDBLOCK, dass derzeit keine weitere Eingabe vorliegt, während EINTR eine Wiederholung erfordern kann. Keines von beiden ist dasselbe Ereignis wie EOF.
Suchen Sie nicht nach einem FIN-Flag im zurückgegebenen Bytepuffer. TCP liefert dieser API einen geordneten Bytestrom; Paketgrenzen und das FIN-Segment sind keine gewöhnliche Anwendungsnutzlast.
Dies ist der Lebenszyklus eines rohen Byte-Tunnels. Ein HTTP-Proxy, der Nachrichten parst, muss weiterhin die HTTP-Rahmung beachten, und ein TLS-terminierender Proxy hat ebenfalls ein TLS-Shutdown-Protokoll. Halten Sie diese Protokollentscheidungen oberhalb des gerichteten TCP-Relays.