Uścisk dłoni SOCKS się powiódł. Teraz przekaźnik czyta od klienta, zapisuje do celu, czeka na pełną odpowiedź i dopiero potem ponownie czyta od klienta. Taka sekwencja może zablokować całkowicie poprawną aplikację.

Gdy tunel TCP jest już ustanowiony, SOCKS nie definiuje wiadomości wewnątrz niego. Cel może wysłać pierwszy. Obie strony mogą wysyłać niezależnie. Jedna strona może wysłać krótki rekord, a następnie czekać na odpowiedź drugiej.

Przekazuj bajty, a nie zgadywane transakcje

Wywołanie odbioru zwraca dostępne bajty zgodnie ze swoimi flagami i stanem gniazda. Nie mówi ogólnemu przekaźnikowi, że odpowiedź aplikacji jest kompletna. Czekanie, aż wypełni się dowolnie duży bufor, może uniemożliwić przesłanie małej wiadomości potrzebnej drugiej stronie do kontynuowania.

Użyj istniejącego modelu współbieżności aplikacji do obsługi obu kierunków: pętli zdarzeń, asynchronicznego I/O lub innego świadomie wybranego projektu. Ważne jest to, że postęp w jednym kierunku nie wymaga wymyślonej granicy wiadomości w drugim.

Utrzymuj dwa ograniczone bufory oczekujące

Dane odczytane od klienta mogą wciąż czekać na dotarcie do celu, podczas gdy dane z celu czekają na dotarcie do klienta. Śledź te oczekujące bajty osobno.

Wysłanie może zapisać mniej bajtów niż zażądano. Zachowaj niezapisany fragment; nie upuszczaj go ani nie odtwarzaj całego bufora. Tymczasowo niezapisywalne gniazdo jest powodem, by czekać na właściwe zdarzenie gotowości, a nie kręcić się bez przerwy.

Ogranicz bufory. Jeśli cel jest wolny, dalsze czytanie nieograniczonych danych klienta po prostu przenosi kolejkę do pamięci przekaźnika. Backpressure oznacza wstrzymanie odczytu, gdy odpowiedni bufor oczekujący jest pełny, i wznowienie, gdy zapisy zwolnią miejsce.

Zakończenie w jednym kierunku wymaga polityki

TCP może zamknąć kierunek wysyłania, podczas gdy drugi kierunek wciąż ma użyteczne dane. Zdecyduj, jak propagować ten stan po opróżnieniu buforowanych bajtów, i odróżnij uporządkowane zamknięcie od błędu lub terminu.

Nic z tego nie wymaga od przekaźnika odszyfrowywania ani analizowania ładunku aplikacji. Potrzebne jest poprawne obsługiwanie strumienia. Samo zwiększenie rozmiaru bufora nie naprawi przekaźnika, który czeka na niewłaściwą stronę lub zakłada, że każdy odczyt odpowiada jednemu całemu żądaniu.

Powiązane artykuły