Przekazywanie półzamknięcia TCP po opróżnieniu oczekujących bajtów
Obsłuż EOF w proxy TCP bez gubienia danych w kolejce i bez odcinania odpowiedzi w drugim kierunku.
Klient kończy wysyłanie, proxy widzi EOF, a odpowiedź znika. Natychmiastowe zamknięcie obu gniazd proxy może spowodować dokładnie taką sekwencję. W przekaźniku TCP uporządkowany koniec w jednym kierunku nie oznacza, że drugi kierunek się zakończył.
Rozważ klienta, który wysyła żądanie, zamyka swoją stronę wysyłania i czeka na odpowiedź:
client -- request, then FIN --> proxy --> service
client <-------- reply ------- proxy <-- service
Proxy ma dwa połączenia TCP i dwa niezależnie poruszające się strumienie bajtów. Musi przekazać dalej sygnał końca danych wejściowych, po przekazaniu bajtów, które go poprzedzają.
Opróżnij kolejkę przed przekazaniem EOF
Przy odbiorze o niezerowym rozmiarze w strumieniu TCP zwrócenie zera oznacza uporządkowany koniec tego przychodzącego strumienia. Oznacz ten kierunek czytania jako zakończony. Przestań czekać na dalsze dane wejściowe z niego, ale zachowaj bajty już umieszczone w kolejce dla przeciwnego gniazda.
Gdy kolejka od klienta do usługi zostanie opróżniona, wywołaj shutdown(service_socket, SHUT_WR) na gnieździe POSIX. To kończy dalszą transmisję w stronę usługi, pozostawiając kierunek od usługi do klienta dostępny. Gdy usługa zakończy swoją odpowiedź, zastosuj operację lustrzaną po opróżnieniu kolejki odpowiedzi.
Zamykanie deskryptorów należy do momentu, w którym oba kierunki i ich oczekujące bufory są zakończone, albo w którym błąd lub anulowanie wymagają zakończenia. Utrzymuj ograniczony limit czasu dla partnera, który nigdy nie kończy swojej pozostałej połowy.
Gotowość to zaproszenie do czytania
Czytelne gniazdo może mieć dane lub stan EOF. Wywołaj recv i zinterpretuj wynik. Liczby dodatnie to bajty do przekazania; zero to koniec kierunku. W gnieździe nieblokującym EAGAIN lub EWOULDBLOCK oznaczają, że obecnie nie ma więcej danych wejściowych, natomiast EINTR może wymagać ponowienia. Żadne z nich nie jest tym samym zdarzeniem co EOF.
Nie szukaj flagi FIN w zwróconym buforze bajtów. TCP dostarcza do tego API uporządkowany strumień bajtów; granice pakietów i segment FIN nie są zwykłym ładunkiem aplikacji.
To jest cykl życia surowego tunelu bajtowego. Proxy HTTP, które parsuje komunikaty, nadal musi respektować ramkowanie HTTP, a proxy kończące TLS ma także protokół zamknięcia TLS. Trzymaj te decyzje protokołowe ponad kierunkowym przekaźnikiem TCP.