Күтіп тұрған байттарды босатып болған соң TCP жартылай жабылуын жіберу
TCP проксиінде EOF-ті кезектегі деректерді жоғалтпай және қарсы бағыттағы жауапты кеспестен өңдеңіз.
Клиент жіберуді аяқтайды, прокси EOF көреді, жауап жоғалады. Проксидің екі сокетін бірден жабу дәл осы реттілікті тудыруы мүмкін. TCP релесінде бір бағыттағы ретті аяқталу қарсы бағыттың біткенін білдірмейді.
Сұраныс жіберіп, жіберу жағын жауып, жауапты күтіп тұрған клиентті қарастырыңыз:
client -- request, then FIN --> proxy --> service
client <-------- reply ------- proxy <-- service
Проксидің екі TCP қосылымы және өз бетінше қозғалатын екі байт ағыны бар. Ол кірістің аяқталу белгісін өзінен бұрын келетін байттарды жібергеннен кейін әрі қарай өткізуі керек.
EOF-ті жіберер алдында кезекті босатыңыз
TCP ағынында нөлдік емес өлшемдегі қабылдау кезінде нөлдің қайтарылуы сол кіріс ағынының ретті аяқталғанын көрсетеді. Ол оқу бағытын аяқталды деп белгілеңіз. Одан әрі кірісті күтуді тоқтатыңыз, бірақ қарсы сокет үшін кезекке қойылған байттарды сақтаңыз.
Клиенттен қызметке кезек босаған соң, POSIX сокетінде shutdown(service_socket, SHUT_WR) шақырыңыз. Бұл қызметке қарай әрі қарай жіберуді аяқтайды, ал қызметтен клиентке бағыты қолжетімді болып қалады. Қызмет өз жауабын бітіргенде, жауап кезегін босатып болған соң айна операциясын қолданыңыз.
Дескрипторларды жабу екі бағыт пен олардың күтіп тұрған буферлері аяқталған нүктеге, немесе қате не бас тарту тоқтатуды талап ететін жерге жатады. Қалған жартысын ешқашан бітірмейтін әріптес үшін шектелген тайм-аут ұстаңыз.
Дайындық — оқуға шақыру
Оқуға болатын сокетте деректер немесе EOF күйі болуы мүмкін. recv шақырып, нәтижесін түсіндіріңіз. Оң сандар — жіберілетін байттар; нөл — бағыттың соңы. Блоктамайтын сокетте EAGAIN немесе EWOULDBLOCK қазір әрі қарай кіріс жоқ екенін білдіреді, ал EINTR қайталап көруді талап етуі мүмкін. Екеуі де EOF-пен бірдей оқиға емес.
Қайтарылған байт буферінен FIN жалауын іздемеңіз. TCP бұл API-ге реттелген байт ағынын жеткізеді; пакет шекаралары мен FIN сегменті қарапайым қолданбалық жүктеме емес.
Бұл шикі байт туннелінің өмірлік циклі. Хабарламаларды талдайтын HTTP проксиі әлі де HTTP қаңқасын сақтауы керек, ал TLS-ті аяқтайтын проксидің де TLS жабу протоколы бар. Бұл протоколдық шешімдерді бағыттық TCP релесінен жоғары ұстаңыз.