Transmiterea semiînchiderii TCP după golirea octeților în așteptare
Gestionați EOF într-un proxy TCP fără a pierde datele din coadă și fără a tăia răspunsul în cealaltă direcție.
Clientul termină trimiterea, proxy-ul vede EOF, iar răspunsul dispare. Închiderea imediată a ambelor socketuri ale proxy-ului poate provoca exact această secvență. Într-un releu TCP, un sfârșit ordonat într-o direcție nu înseamnă că cealaltă direcție s-a terminat.
Luați în considerare un client care trimite o cerere, își închide partea de trimitere și așteaptă răspunsul:
client -- request, then FIN --> proxy --> service
client <-------- reply ------- proxy <-- service
Proxy-ul are două conexiuni TCP și două fluxuri de octeți care se mișcă independent. Trebuie să ducă mai departe indicația de sfârșit al intrării, după ce a dus octeții care o precedă.
Goliți coada înainte de a transmite EOF
La o recepție de dimensiune nenulă pe un flux TCP, returnarea zero indică un sfârșit ordonat al acelui flux de intrare. Marcați acea direcție de citire ca terminată. Opriți așteptarea altor date de intrare din ea, dar păstrați octeții deja puși în coadă pentru socketul opus.
După ce coada de la client la serviciu s-a golit, apelați shutdown(service_socket, SHUT_WR) pe un socket POSIX. Aceasta încheie transmisia ulterioară către serviciu, lăsând disponibilă direcția de la serviciu la client. Când serviciul își termină răspunsul, aplicați operația oglindită după golirea cozii răspunsului.
Închiderea descriptorilor aparține momentului în care ambele direcții și bufferele lor în așteptare s-au terminat, sau în care o eroare ori o anulare impun terminarea. Păstrați un timp de așteptare mărginit pentru un partener care nu își finalizează niciodată jumătatea rămasă.
Disponibilitatea este o invitație de a citi
Un socket care poate fi citit poate avea date sau o stare EOF. Apelați recv și interpretați rezultatul. Valorile pozitive sunt octeți de transmis; zero este sfârșitul direcției. Pe un socket neblocant, EAGAIN sau EWOULDBLOCK înseamnă că momentan nu mai există date de intrare, în timp ce EINTR poate impune o nouă încercare. Niciuna nu este același eveniment ca EOF.
Nu căutați un indicator FIN în bufferul de octeți returnat. TCP livrează acestui API un flux ordonat de octeți; limitele pachetelor și segmentul FIN nu sunt payload obișnuit al aplicației.
Acesta este ciclul de viață al unui tunel de octeți brut. Un proxy HTTP care analizează mesaje trebuie totuși să respecte încadrarea HTTP, iar un proxy care termină TLS are și un protocol de închidere TLS. Țineți aceste decizii de protocol deasupra releului TCP direcțional.