Кліент сканчае адпраўку, проксі бачыць EOF, і адказ знікае. Неадкладнае закрыццё абодвух сокетаў проксі можа выклікаць менавіта такую паслядоўнасць. У TCP-рэле ўпарадкаванае завяршэнне ў адным кірунку не азначае, што іншы кірунак скончаны.

Разгледзім кліента, які адпраўляе запыт, закрывае бок адпраўкі і чакае адказу:

client -- request, then FIN --> proxy --> service
client <-------- reply ------- proxy <-- service

У проксі два TCP-злучэнні і два незалежна рухомыя патокі байтаў. Ён павінен перадаць далей прыкмету канца ўводу пасля перадачы байтаў, якія ёй папярэднічаюць.

Спусціце чаргу перад перадачай EOF

Для прыёму ненулявога памеру ў патоку TCP вяртанне нуля паказвае на ўпарадкаванае завяршэнне гэтага ўваходнага патоку. Пазначце гэты кірунак чытання як завершаны. Спыніце чаканне новых даных ад яго, але захавайце байты, ужо пастаўленыя ў чаргу для супрацьлеглага сокета.

Пасля спустошвання чаргі ад кліента да службы выклічце shutdown(service_socket, SHUT_WR) на сокеце POSIX. Гэта спыняе далейшую перадачу да службы, пакідаючы кірунак ад службы да кліента даступным. Калі служба скончыць свой адказ, прымяніце люстэркавую аперацыю пасля спустошвання чаргі адказу.

Закрыццё дэскрыптараў належыць да моманту, калі абодва кірункі і іх чаканыя буферы завершаны, або калі памылка ці скасаванне патрабуюць спынення. Трымайце абмежаваны тайм-аўт для партнёра, які ніколі не завяршае сваю пакінутую палову.

Гатоўнасць — гэта запрашэнне да чытання

Сокет, даступны для чытання, можа мець даныя або стан EOF. Выклічце recv і інтэрпрэтуйце вынік. Дадатныя лікі — гэта байты для перадачы; нуль — канец кірунку. На неблакуючым сокеце EAGAIN або EWOULDBLOCK азначае, што цяпер больш няма ўводу, а EINTR можа патрабаваць паўтору. Ні адно з іх не з'яўляецца тым жа падзеяй, што і EOF.

Не шукайце сцяг FIN у вернутым буферы байтаў. TCP перадае ў гэты API упарадкаваны паток байтаў; межы пакетаў і сегмент FIN не з'яўляюцца звычайнай карыснай нагрузкай праграмы.

Гэта жыццёвы цыкл сырога байтавага тунэля. HTTP-проксі, які разбірае паведамленні, усё яшчэ павінен паважаць фарматаванне HTTP, а проксі, які завяршае TLS, таксама мае пратакол завяршэння TLS. Трымайце гэтыя пратакольныя рашэнні вышэй за кірункавае TCP-рэле.

Падобныя артыкулы