Поўнадуплексны паток і супрацьціск у рэлеі SOCKS
Будуйце паток рэлея вакол незалежных байтавых патокаў, частковага I/O, абмежаваных буфераў і супрацьціску, а не здагадак пра памеры адказу.
Рукаўцісканне SOCKS прайшло паспяхова. Цяпер рэлей чытае ад кліента, піша ў пункт прызначэння, чакае поўнага адказу і толькі потым зноў чытае ад кліента. Такая паслядоўнасць можа заблакаваць цалкам слушную праграму.
Пасля стварэння TCP-тунэля SOCKS не вызначае паведамленні ўнутры яго. Пункт прызначэння можа адправіць першым. Абодва бакі могуць адпраўляць незалежна. Адзін бок можа адправіць кароткі запіс і потым чакаць адказу другога.
Перадавайце байты, а не меркаваныя транзакцыі
Выклік прыёму вяртае даступныя байты ў адпаведнасці са сваімі сцягамі і станам сокета. Ён не паведамляе агульнаму рэлею, што адказ праграмы завершаны. Чаканне запаўнення адвольна вялікага буфера можа перашкодзіць перадачы кароткага паведамлення, патрэбнага партнёру для працягу.
Выкарыстоўвайце існуючую мадэль паралельнасці праграмы для абслугоўвання абодвух кірункаў: цыкл падзей, асінхронны I/O або іншы свядома абраны дызайн. Важныя паводзіны: прагрэс у адным кірунку не патрабуе выдуманай мяжы паведамлення ў другім.
Трымайце два абмежаваныя буферы чакання
Даныя, прачытаныя ад кліента, могуць яшчэ чакаць дасягнення пункта прызначэння, а даныя ад пункта прызначэння чакаюць дасягнення кліента. Адсочвайце гэтыя байты чакання асобна.
Адпраўка можа запісаць менш байтаў, чым запытана. Захавайце незапісаную частку; не адкідвайце яе і не прайгравайце ўвесь буфер. Часова незапісваемы сокет — гэта падстава чакаць адпаведнай падзеі гатоўнасці, а не круціцца безупынна.
Абмяжуйце буферы. Калі пункт прызначэння павольны, працяг чытання неабмежаваных даных кліента проста пераносіць чаргу ў памяць рэлея. Супрацьціск азначае прыпыненне чытання, калі адпаведны буфер поўны, і аднаўленне, калі запіс вызваляе месца.
Канец у адным кірунку патрабуе палітыкі
TCP можа зачыніць кірунак адпраўкі, пакуль другі кірунак яшчэ мае карысныя даныя. Вырашыце, як перадаць гэтую ўмову пасля спусташэння буфераваных байтаў, і адрознівайце ўпарадкаванае закрыццё ад памылкі ці тэрміну.
Нішто з гэтага не патрабуе, каб рэлей расшыфроўваў або разбіраў карысную нагрузку праграмы. Яму патрэбна правільная апрацоўка патоку. Павелічэнне памеру буфера само па сабе не выправіць рэлей, які чакае не той бок або лічыць, што кожнае чытанне адпавядае аднаму цэламу запыту.