Stream, neboli proud
Dalším významným rozdílem mezi přenosovými službami protokolů TCP a UDP je také jejich pohled na přenášená data. Jak jsme si již naznačili minule, protokol UDP očekává od své bezprostředně vyšší vrstvy vždy celý blok dat, který se snaží přenést opět jako celek (v rámci jediného tzv. uživatelského datagramu, viz minule), a na straně příjemce jej předává své bezprostředně vyšší vrstvě opět jako celek.
Naproti tomu protokol TCP se snaží nabízet své bezprostředně vyšší vrstvě přenos jednotlivých bytů. Očekává tedy, že entity aplikační vrstvy mu na straně odesilatele budou postupně předávat jednotlivé byty (přesněji: osmibitové oktety), a na straně příjemce si je zase budou po jednom vyzvedávat. Tím vzniká iluze proudu (anglicky: stream) jednotlivých bytů, který navíc není nijak strukturován - tj. všechny přenášené byty jsou považovány za rovnocenné. Ve skutečnosti samozřejmě nejsou jednotlivé bity přenášeny každý zvlášť. Protokol TCP na straně odesilatele postupně akumuluje jednotlivé byty do vhodné vyrovnávací paměti (bufferu), a po jejím naplnění odešle celý její obsah najednou - v tzv. segmentu, jak se nazývá blok, přenášený protokolem TCP. Analogicky na straně příjemce, kde se datový obsah segmentu ukládá do vyrovnávací paměti, a jednotlivé byty jsou entitám aplikační vrstvy poskytovány z této vyrovnávací paměti. Celý mechanismus sdružování jednotlivých bytů do bloků je plně v režii protokolu TCP, který se přenosem větších celků snaží optimalizovat využití přenosových cest. Pro vyšší vrstvu je tento mechanismus neviditelný - vyší vrstva pracuje s představou proudu jednotlivých bytů. Existují však takové aplikace, pro které právě naznačený mechanismus není příliš vhodný. Příkladem mohou být tzv. vzdálené terminálové relace, uskutečňované prostřednictvím sítě - kdy jeden uzlový počítač vystupuje v roli terminálu jiného počítače a jednotlivé znaky, zadané z jeho klávesnice, posílá ke zpracování tomuto druhému počítači (který mu zase posílá zpět vše, co má být zobrazeno na obrazovce terminálu). Kdyby v takovéto situaci protokol TCP čekal, až vstupní znaky naplní vyrovnávací paměť na straně odesilatele a teprve pak je skutečně odeslal, uživatel by hodně dlouho mačkal klávesy bez jakékoli odezvy. Protokol TCP však i s tímto počítá, a nabízí odesilateli mechanismus (označovaný jako push), kterým si aplikace může vynutit skutečné odeslání dat i v případě, že příslušná vyrovnávací paměť není ještě naplněna.Jak se dosahuje spolehlivost
Již dříve jsme si naznačili, že prakticky jedinou možností, jak pomocí nespolehlivé přenosové služby zajistit spolehlivé přenosy, je umožnit příjemci rozpoznat chybně přenesený blok, a vyžádat si jeho opětovné vyslání.
Ukázali jsme si také, že za tímto účelem se používá více různých způsobů tzv. potvrzování (acknowledgement). Protokol TCP používá tzv. kladné potvrzování (positive acknowledgement), což znamená, že potvrzuje úspěšně přijatá data, a na chybně přijatá data nereaguje nijak (ty pak odesilatel znovu vyšle na základě vypršení časového limitu, ve kterém očekával jejich kladné potvrzení). Ve své základní podobě tzv. jednotlivého kladného potvrzování (stop&wait positive acknowledgement), kdy odesilatel před odesláním každého dalšího bloku čeká na kladné potvrzení naposledy vyslaného bloku, je tento mechanismus značně neefektivní. Protokol TCP proto používá kladné potvrzování ve variantě tzv. kontinuálního potvrzování (continuous acknowledgement), známého též jako tzv. metoda okénka (sliding window). Podstata této varianty spočívá v tom, že odesilatel může odeslat další blok (resp. několik dalších bloků) ještě dříve, než dostane potvrzení o přijetí bloku předchozího. O tom, kolik bloků může takto vyslat "dopředu", rozhoduje velikost pomyslného okénka. Když jsme se zabývali různými metodami potvrzování, předpokládali jsme, že potvrzovanými jednotkami jsou celé bloky dat. V případě protokolu TCP se přenášené bloky dat označují jako segmenty, a mohou mít různou délku. V případě, že některý segment není přenesen bezchybně (resp. není kladně potvrzen do vypršení časového limitu), je jeho obsah vyslán znovu, a po něm také obsah všech následujících segmentů. Jde tedy o tzv. opakování s návratem (Go-Back-N), viz opět 30. díl. Podstatné ale je, že při tomto opakovaném vysílání již jednou vyslaných dat nemusí být dodrženy původní velikosti segmentů - znovu vyslaný segment může být větší než segment, vyslaný původně. To ale činí potvrzování celých segmentů problematické. Proto jsou v protokolu TCP potvrzovanými jednotkami dat nikoli celé bloky (segmenty), ale jednotlivé byty (přesněji: oktety)!! Konkrétní způsob implementace potvrzování v protokolu TCP využívá plně duplexního charakteru spojení na úrovni transportní vrstvy. Jak naznačuje obrázek 57.1., každý segment obsahuje kromě vlastních dat i údaj o pozici prvního bytu těchto dat v rámci celého proudu bytů (tzv. sequence number). S využitím tohoto údaje pak příjemce původní proud bytů rekonstruuje. Jednotlivá kladná potvrzení se opět vztahují k celým bytům, a jsou vkládána do segmentů, přenášených v opačném směru, než potvrzovaná data. Jde tedy o tzv. nesamostatné potvrzování (anglicky: piggybacking). Kladné potvrzení má přitom formu čísla pozice prvního bytu (v rámci proudu), který příjemce očekává jako další (tj. prvního bytu za posledním úspěšně přijatým) - jde o tzv. acknowledgement number. Protokol TCP - II. V minulém dílu jsme se začali zabývat protokolem TCP. Řekli jsme si, že své bezprostředně vyšší vrstvě poskytuje přenosové služby spolehlivého a spojovaného charakteru, i když k jejich zajištění může sám využívat jen nespolehlivé (a nespojované) přenosové služby na úrovni síťové vrstvy, poskytované protokolem IP. Naznačili jsme si také, že potřebné spolehlivosti dosahuje protokol TCP pomocí potvrzování a opakovaného vysílání chybně přenesených dat. Dnes se zastavíme podrobněji právě u způsobu opakování přenosů.Připomeňme si však ještě jednou to, co jsme si o konkrétním mechanismu potvrzování řekli již minule: protokol TCP používá tzv. kladné potvrzování (positive acknowledgement), což znamená, že potvrzuje pouze správně přijatá data, zatímco na chybně přijatá data nereaguje nijak. Odesilatel proto pozná, že určitá data nebyla přenesena správně, až po vypršení určitého časového limitu. Současně s tím je ale dobré si uvědomit, že také kladná potvrzení jsou sama přenášena pomocí stejně nespolehlivých přenosových služeb síťové vrstvy, jako samotná data. Může se proto stát, že určitá data jsou přenesena bezchybně, ale "ztratí" se jejich kladné potvrzení. Odesilatel však nemá možnost oba tyto případy rozlišit. Vždy musí čekat až do vypršení časového limitu, zda nedostane kladné potvrzení, a pokud ne, musí data vyslat znovu.
Otázkou ovšem je, jak volit příslušný časový limit (timeout)? Bude-li příliš krátký, může docházet k situacím, kdy data budou přenesena bezchybně, ale jejich kladné potvrzení dojde odesilateli příliš pozdě - až po vypršení časového limitu, což odesilatele přinutí znovu vyslat úspěšně přenesená data. V opačném případě - bude-li časový limit příliš dlouhý - bude odesilatel zase zbytečně dlouho čekat, než si bude moci domyslet, že se data nepřenesla správně. V obou případech je výsledkem neefektivní využití přenosových kapacit. Problém vhodné volby časového limitu je navíc komplikován skutečností, že protokol TCP může být používán v různých sítích, ve kterých se doby přenosu mohou lišit i v několika řádech. Například v rychlé lokální síti by příslušný časový limit měl být výrazně kratší než v rozlehlé síti, která používá relativně velmi pomalé pevné telefonní okruhy. Situace je navíc ještě komplikovanější u vzájemně propojených sítí (internets, s malým "i"), kde jednotlivé části přenosové trasy (route) mají obecně různé přenosové kapacity, a kde se navíc trasa mezi dvěma koncovými účastníky může v průběhu přenosu dynamicky měnit (např. v důsledku zahlcení či výpadku).Adaptivní chování
Způsob, jakým se protokol TCP vyrovnává s problémem správné volby časového limitu pro opakované vysílání (retransmission), lze v prvním přiblížení charakterizovat jako adaptivní. TCP totiž průběžně monitoruje skutečné chování přenosové sítě, a podle něj se snaží předvídat její chování i pro nejbližší časový úsek. Tomu pak přizpůsobuje i své chování.
TCP neustále měří dobu obrátky (RTT, round trip time) jako dobu od odeslání dat do přijetí kladného potvrzení o jejich úspěšném doručení. Časový limit pak uzpůsobuje průměrné době obrátky, kterou vypočítává jako vážený průměr (weighted average) jednotlivých naměřených dob obrátky.
Nejednoznačnost potvrzování
V minulém dílu jsme si také říkali, že protokol TCP nepotvrzuje celé segmenty (jak se nazývají jím přenášené bloky dat), ale jednotlivé byty (přesněji: oktety) v rámci přenášeného proudu (stream). To má jeden závažný důsledek pro výpočet doby odezvy. Představme si situaci, kdy odesilatel nedostane do časového limitu kladné potvrzení o přijetí určité části dat, a tak je vyšle znovu ve stejně velkém segmentu. Dostane-li pak kladné potvrzení, není z něj schopen rozlišit, ke kterému segmentu se toto potvrzení vztahuje - zda jde o potvrzení poprvé vyslaných dat (které se někde zdrželo), nebo zda jde již o potvrzení podruhé vyslaných dat (zatímco poprvé vyslaná data se přenesla s chybou, nebo se jejich kladné potvrzení ztratilo). Potvrzování, používané protokolem TCP, je proto v obecném případě nejednoznačné (ambiquous).Z pohledu zabezpečení spolehlivého přenosu tato nejednoznačnost nijak nevadí, ale problém vzniká při výpočtu doby obrátky: má tato být vztažena k okamžiku prvního vyslání, nebo naopak k okamžiku posledního opakovaného vyslání určitých dat? Dá se ukázat, že obě varianty jsou špatné - v případě té první může vážený průměr doby obrátky růst nade všechny meze, zatímco ve druhém případě sice konverguje k určité konečné hodnotě, ale tato je menší, než by správně měla být (praktické implementace této varianty ukazují, že je tato hodnota přibližně poloviční oproti správné, a protokol TCP pak vysílá všechna data právě dvakrát).
Karnův algoritmus
S jednoduchým a elegantním řešením poprvé přišel radioamatér Phil Karn, když se snažil implementovat TCP/IP protokoly i pro prostředí radioamatérských paketových sítí (což se mu ostatně povedlo - výsledkem je známý programový balík KA9Q, nazvaný podle volací značky svého autora).
Myšlenka, se kterou Karn přišel, je velmi jednoduchá - v případě nejednoznačného potvrzení (tj. v případě opakovaného vyslání již jednou vyslaných dat) vůbec neměřit dobu obrátky, a tudíž i neuzpůsobovat podle ní časový limit. Jinými slovy: pro stanovení časového limitu využívat pouze ty případy, kdy data byla vyslána jen jednou, a je tudíž jasné, jak dobu obrátky měřit.
I toto řešení však ve své čisté podobě není příliš použitelné. Představme si totiž situaci, kdy například vlivem změny trasy či výpadku části přenosových kapacit náhle vzroste zpoždění při přenosu. Potvrzení nestihne přijít včas, a tak jsou data vyslána znovu - v důsledku toho se pak ale neměří doba obrátky, a nijak se nemění ani časový limit. Bude-li nárůst zpoždění trvalý, výše uvedený algoritmus na něj vůbec nezareaguje! Konkrétní algoritmus, který Phil Karn navrhl, však řeší i tuto situaci (technikou, označovanou jako timer backoff): v okamžiku, kdy začne docházet k opakovanému vysílání dat, přestává tento algoritmus měřit dobu obrátky, a nemění tudíž ani vážený průměr těchto dob. Začne ale zvětšovat časový limit (např. na dvojnásobek po každém opakovaném vyslání dat). Teprve v okamžiku, kdy díky většímu časovému limitu dostane kladné potvrzení včas (tj. jako jednoznačné potvrzení), změří skutečnou dobu obrátky, znovu začne vypočítávat vážený průměr dob obrátky, a tomuto průměru pak uzpůsobí časový limit. Protokol TCP - III. V minulém dílu jsme se zabývali tím, jak se protokol TCP vyrovnává s různou propustností přenosových cest, a jak dokáže dynamicky přizpůsobovat svůj mechanismus potvrzování okamžitým změnám tzv. doby obrátky. K tomu, aby protokol TCP dokázal co nejefektivněji využít existující přenosové kapacity, to ale ještě nestačí. Dalším důležitým předpokladem pro zajištění spolehlivého, ale současně s tím i dostatečně efektivního přenosu, je vhodné řízení toku (flow control). Protokol TCP musí zajistit, aby odesilatel neposílal data rychleji, než je příjemce schopen je přijímat (resp. ukládat do svých vyrovnávacích pamětí). Pokud by totiž odesilatel příjemce "zahltil", tento by musel přijímaná data zahazovat, a ta by musela být posléze vysílána znovu. Odesilatel se tedy nutně musí řídit kapacitními možnostmi příjemce. Konkrétní způsob, jakým se v protokolu TCP dosahuje potřebného řízení toku, bezprostředně souvisí s mechanismem potvrzování.Okénko proměnlivé velikosti
Když jsme si dílu popisovali mechanismus potvrzování v protokolu TCP, řekli jsme si, že jde o tzv. kladné potvrzování (tj. takové, kdy příjemce kladně potvrzuje správně přijatá data, a na chybně přenesená data nereaguje). Protokol TCP ovšem používá tento způsob potvrzování v tzv. kontinuální variantě, kdy umožňuje, aby odesilatel vysílal data "dopředu", tedy ještě dříve, než dostane potvrzení o úspěšném přijetí dříve vyslaných dat. Existuje zde samozřejmě určité omezení na objem dat, které se takto mohou vyslat "dopředu", a je dáno velikostí posuvného datového okénka (sliding window). Okamžitá velikost a poloha tohoto okénka určuje odesilateli, kolik dat ještě může vyslat, aniž by musel čekat na potvrzení od protější strany.Příjemce má samozřejmě možnost řídit tok dat tím, že dočasně pozdrží kladné potvrzení úspěšně přijatých dat. Tím totiž zabrání odesilateli, aby si posunul své datové okénko, a nedovolí mu tudíž vyslat další data za okamžitým koncem okénka. Tato metoda má ale nepříjemný vedlejší efekt v tom, že když příjemce pozdrží kladné potvrzení a odesilatel jej nedostane do příslušného časového limitu (viz minule), bude to interpretovat tak, že tato data nebyla úspěšně přenesena. V důsledku toho pak odesilatel znovu odešle již jednou odeslaná a úspěšně přijatá data. Tato sice již nemohou příjemce "zahltit" (ten je může jednoduše ignorovat), ale jejich přenos zbytečně spotřebovává část existující přenosové kapacity.
Protokol TCP proto používá jiný způsob řízení toku, kterým je změna velikosti posuvného okénka. Příjemce reaguje na každý úspěšný přenos dat tím, že pošle příslušné kladné potvrzení, a odesilatel si na základě tohoto potvrzení příslušným způsobem posune své datové okénko. Současně s tímto potvrzením ale příjemce zašle odesilateli ještě i další údaj, podle kterého si odesilatel nově nastaví šířku svého datového okénka.
Příjemce tento údaj samozřejmě volí podle svých možností tak, aby vždy byl schopen přijmout to, co mu odesilatel pošle. Příjemce dokonce může odesilateli zmenšit jeho datové okénko až na nulovou velikost, a tím vlastně zcela zastavit vysílání jakýchkoli dat. Příjemce by ale při stanovování nové velikosti okénka měl vždy postupovat korektně - jelikož nemůže přesně určit okamžik, kdy odesilatel dostane údaj o nové velikosti okénka, neměl by se jeho pravý okraj nikdy posouvat zpět.
Nejde jen o koncové účastníky
Potřeba řídit tok dat se však netýká jen obou koncových účastníků přenosu. Je totiž nutné si uvědomit, že na cestě od odesilatele k příjemci mohou data procházet i přes několik přepojovacích uzlů (gateways), které také mají jen konečnou propustnost. Odesilatel tedy musí dávat pozor i na to, aby nezpůsobil zahlcení (tzv. zácpu, angl. congestion) těchto mezičlánků.
Protokol TCP však neobsahuje žádný explicitní mechanismus, který by měl za úkol ochranu těchto mezičlánků před zahlcením (congestion control). Snaží se ale chovat tak, aby k zahlcování mezilehlých přepojovacích uzlů nedocházelo. Pro správné pochopení podstaty celého problému je vhodné si uvědomit, jak se takové zahlcení mezilehlého uzlu projeví koncovým účastníkům komunikace. Jakmile přepojovací uzel (gateway) nestačí přepojovat přenášená data v reálném čase, tato se hromadí v jeho vstupních frontách, kde čekají na své další zpracování. Tento stav se koncovým účastníkům projevuje růstem doby obrátky. Jakmile ale zatížení přepojovacího uzlu stoupne natolik, že jeho vstupní fronty již svou kapacitou nestačí, musí přepojovací uzel nově přijímané bloky dat zahazovat, protože je nemá kam uložit. Mechanismy potvrzování, které se snaží zajistit spolehlivý přenos, reagují na obě tyto situace opakovaným vysíláním již jednou vyslaných dat, tedy vlastně dalším zvýšením provozu v síti, což dále zhoršuje přetížení přepojovacích uzlů, a může vést až k úplnému zhroucení sítě v důsledku zahlcení (congestion collapse). Jednou z možností, jak předcházet zahlcování přepojovacích uzlů, je dát jim možnost upozornit odesilatele na hrozící nebezpečí. To však opět stojí určitou část přenosové kapacity. Další, méně nákladnou možností, je vhodná disciplína samotných odesilatelů.Protokol TCP se snaží předcházet zahlcování přepojovacích uzlů tím, že odesilatel si sám zmenšuje šířku svého datového okénka v situaci, kdy předpokládá hrozící zahlcení přepojovacích uzlů. Každou ztrátu datového segmentu (tj. každý případ, kdy nedostane kladné potvrzení do příslušného časového limitu), interpretuje odesilatel jako důsledek zahlcení některého z přepojovacích uzlů na cestě k příjemci, a reaguje na to tím, že si sám zúží své datové okénko na polovinu (současně s tím prodlužuje na dvojnásobek i časový limit, do kterého očekává kladné potvrzení, viz minule). Při opakovaných ztrátách přenášených segmentů tak velikost okénka exponenciálně klesá, čímž se odesilatel snaží maximálně snížit objem provozu v síti, a poskytnout tak přepojovacím uzlům potřebný čas na zotavení. Tato technika je označována jako Multiplicative Decrease Congestion Avoidance.
Otázkou ovšem je, jak má protokol TCP reagovat na konec stavu zahlcení. Kdyby začal opět exponenciálně zvětšovat velikost svého datového okénka, vedlo by to na prudkou oscilaci celé přenosové sítě mezi stavem s minimálním objemem přenosů a stavem zahlcení. Proto musí protokol TCP postupovat "umírněněji", a své datové okénko zvětšovat pomaleji (způsobem, který je označován jako slow-start recovery, doslova: zotavení s pomalým startem). Za každý úspěšně přenesený segment si odesilatel zvětší své datové okénko jen o velikost tohoto segmentu. Jakmile však dosáhne poloviny té velikosti okénka, kterou mu nabízí příjemce (viz výše), postupuje ještě pomaleji, a velikost okénka zvětšuje vždy až poté, co dostane kladné potvrzení o úspěšném přenosu všech segmentů v rámci celého okénka. Maximální velikostí okénka je pak samozřejmě ta, kterou mu signalizuje příjemce. Kombinací všech výše uvedených mechanismů pro řízení toku, spolu s adaptivním způsobem potvrzování (o kterém jsme si povídali minule) dosahuje protokol TCP velmi efektivního využití existujících přenosových kapacit. Praktické testy ukázaly, že oproti prvním verzím protokolu TCP, které uvedené mechanismy ještě nepoužívaly, dosahují novější verze TCP dvakrát až desetkrát většího přenosového výkonu. To je jistě jeden z hlavních důvodů dnešní velké popularity protokolu TCP. Protokol TCP - IV. Po předcházejících třech dílech, ve kterých jsme se zabývali celkovou filosofií protokolu TCP a jeho přístupem k řešení různých problémů, již můžeme být poněkud konkrétnější. Můžeme si ukázat přesný formát datových bloků, se kterým protokol TCP pracuje.Nejprve si ale připomeňme, že bloky dat, přenášené protokolem TCP jako celek, se označují jako segmenty (segments), zatímco v případě alternativního protokolu UDP jde o tzv. uživatelské datagramy (user datagrams). V obou případech je přenášený datový blok tvořen dvěma hlavními částmi: hlavičkou (header) a vlastními daty. Zatímco ale v případě protokolu UDP stačí, když hlavička kromě zabezpečovacího údaje a příznaku délky obsahuje již jen údaj o portu koncového příjemce a odesilatele, hlavička TCP segmentu musí být obsažnější - jak je ostatně možné očekávat v případě výrazně složitějšího přenosového protokolu.
Čím je určeno spojení
Spojované (connection-oriented) protokoly, mezi které patří i protokol TCP, musí vždy nějakým způsobem identifikovat konkrétní spojení, po kterém jsou určitá data přenášena. Spojované protokoly síťové vrstvy mají blíže k představě spojení jako kanálu, který někudy vede, a tak jej obvykle označují jednoznačným identifikátorem (např. číslem). Tento identifikátor pak používají jak pro zanesení příslušné cesty do směrovacích tabulek mezilehlých uzlů, přes které spojení prochází, tak i ve vlastních datových paketech pro určení cesty, kterou mají být přenášeny (místo adresy příjemce). Spojované protokoly na úrovni transportní vrstvy (což je případ protokolu TCP) však již "nevidí" žádné mezilehlé uzly, nepotřebují brát je v úvahu, a je pro ně přirozenější identifikovat spojení dvojicí: .Co je ale koncovým a počátečním bodem spojení v případě protokolu TCP? IP adresa příjemce a odesilatele nestačí, neboť ta jednoznačně identifikuje pouze uzlový počítač, a nikoli již konkrétní entitu aplikační vrstvy v rámci daného uzlu. Obdobně není samo o sobě dostatečné ani číslo portu , které zase identifikuje aplikační entitu v rámci daného počítače. Počáteční (a stejně tak i koncový) bod spojení může být určen až dvojicí <IP adresa, číslo portu>.
Jak ovšem vyplývá, v TCP segmentu jsou vyjádřeny pouze čísla portů odesilatele a příjemce. Potřebné IP adresy jsou pak, obdobně jako v případě protokolu UDP, součástí tzv. pseudohlavičky, která je shodná s pseudohlavičkou protokolu UDP (samozřejmě až na obsah pole PROTO, které identifikuje transportní protokol, a pro TCP má hodnotu 6). Stejný jako u protokolu UDP je i význam pseudohlavičky a způsob jejího využití - je zahrnuta do výpočtu kontrolního součtu (položka CHECKSUM v TCP segmentu), ale ve skutečnosti přenášena není. Obsah jednotlivých položek (především pak obě IP adresy) dostává transportní vrstva na straně příjemce od vrstvy síťové. Kladné potvrzování Z předchozích dílů již také víme, že protokol TCP používá kladné potvrzování - nikoli ovšem celých bloků (segmentů), ale jednotlivých bytů (osmibitových oktetů). Příjemce i odesilatel se dívají na přenášená data jako na lineární posloupnost bytů, a v každém segmentu se vlastně přenáší část této lineární posloupnosti. Která část to je, udává položka SEQUENCE NUMBER v hlavičce segmentu (vyjadřující pozici prvního přenášeného bytu v této posloupnosti). Kladné potvrzení, které příjemce vrací odesilateli v případě úspěšného příjmu, pak má opět formu pozice bytu v uvažované lineární posloupnosti - tentokráte ale pozice prvního bytu, který příjemce očekává jako další (položka ACKNOWLEDGEMENT NUMBER). V položce WINDOW je pak vyjádřena velikost datového okénka, které příjemce nabízí odesilateli, a které ve své podstatě signalizuje, kolik volného místa ve své vyrovnávací paměti má příjemce ještě k dispozici (viz minulý díl).Je dobré si uvědomit, ke kterému směru přenosu se obsah tří právě uvedených položek vztahuje. Uvažujeme-li segment, směřující od uzlu A do uzlu B, týká se jeho položka SEQUENCE NUMBER přenosu v témže směru (tj. od A do B), zatímco potvrzení v položce ACKNOWLEDGEMENT NUMBER se vztahuje k přenosu dat v opačném směru (tj. od B do A). Stejně tak se i obsah položky WINDOW týká přenosu dat v opačném směru (od B do A).
Naléhavá data
Jak jsme si již také naznačili, protokol TCP nabízí své přenosové služby ve formě proudu (stream) jednotlivých bytů - odesilatel na jedné straně zadává k odeslání postupně jednotlivé byty, a příjemce si je na druhé straně ve stejném pořadí vyzvedává. Lze si tedy představit, že protokol TCP implementuje pomyslnou rouru, do které odesilatel z jedné strany jednotlivé byty vkládá, a příjemce si je z druhé strany zase odebírá. Uvnitř této roury se však může nacházet nezanedbatelný počet bytů, které již byly odeslány, ale nebyly dosud přijaty. A to může u některých aplikací způsobovat nemalé problémy. Například při vzdáleném přístupu pomocí terminálové emulace se uvnitř pomyslné roury nachází znaky, které uživatel již zadal z klávesnice, ale které ještě nebyly hostitelským počítačem přijaty a zpracovány. Potřebuje-li však uživatel náhle zadat vhodný povel k přerušení právě probíhající činnosti (tzv. break), musely by příslušné řídící znaky postupně projít rourou a mohly by se uplatnit až teprve tehdy, když budou zpracovány všechny předtím zadané znaky.Protokol TCP však právě pro tyto účely nabízí možnost "předbíhání", dovolující vyslat příslušné povely jako tzv. naléhavá data (urgent data), někdy označovaná též jako data mimo pořadí (out-of-band data). Příznak toho, že daný segment obsahuje naléhavá data, je vyjádřen nastavením příslušného bitu v položce CODE BITS. Vlastní naléhavá data pak musí být umístěna od začátku datové části segmentu, a v položce URGENT POINTER je ukazatel na jejich konec v rámci daného segmentu.
Po doručení naléhavých dat by měl být koncový příjemce neprodleně upozorněn na jejich existenci. Samotný protokol TCP však již nestanovuje, jakým způsobem se tak má dít. Ostatně ani dost dobře nemůže, neboť příslušný mechanismus závisí na konkrétní implementaci. Další řídící bity v šestibitové položce CODE BITS pak slouží mj. potřebám navazování a rušení spojení, operaci push, umožňují zneplatnit položku ACKNOWLEDGEMENT NUMBER atd.
Segment ani jeho hlavička nemají pevnou délku
Velikost datové části segmentu, a tím i segmentu jako takového, není pevná, a stejně tak nemusí být stejně velké ani segmenty, přenášené postupně v rámci téhož spojení. Celková délka segmentu (tj. jeho datové části i hlavičky) přitom není vyjádřena přímo v segmentu samotném, ale až v jeho pseudohlavičce (položka TCP LENGTH).
Otázkou ovšem je, jak volit optimální velikost segmentu. Zde je nutné si uvědomit, že jednotlivé segmenty jsou vkládány do IP datagramů, a ty zase do rámců (na úrovni rámců vrstvy síťového rozhraní) - každý z nich si ale k "užitečným" datům přidává svá řídící data, která představují režii přenosu. V případě malých segmentů je tato režie relativně velká, zatímco v případě velkých segmentů dochází k fragmentaci, když nelze umístit celé segmenty resp. IP datagramy do přenosových rámců. Optimální by byl co největší segment, při kterém ještě nebude docházet k žádné fragmentaci. Najít jeho velikost je ale velmi netriviální (tato velikost totiž závisí na mnoha faktorech, které se navíc mohou dynamicky měnit). Samotný protokol TCP neobsahuje žádný mechanismus pro nalezení optimální velikosti segmentu.Co však protokol TCP nabízí, je prostředek, pomocí kterého se obě strany mohou dohodnout alespoň na maximální velikosti přenášených segmentů. Implicitně používá TCP maximum, které odpovídá datové části segmentu o velikosti 536 bytů (tak, aby se segment včetně své obvyklé hlavičky vešel do IP datagramu implicitní velikosti 576 bytů). Tato implicitní hodnota je založena spíše na pesimistickém předpokladu, že spojení mezi oběma koncovými účastníky není přímé, ale vede přes jednu či několik bran, a má malou propustnost. Pokud jsou však oba koncoví účastníci připojeni například k témuž segmentu rychlé lokální sítě, je jistě žádoucí, aby plně využívali její větší šířku přenosového pásma a její schopnost přenášet najednou větší bloky dat. Tedy volit větší maximální velikost segmentů.
Konkrétní mechanismus pro stanovení maximální velikosti segmentu využívá volitelné položky OPTIONS v hlavičce segmentu. Je-li ovšem tato položka volitelná, stejně tak jako je proměnná její délka, nemůže mít pevnou délku ani samotná hlavička TCP segmentu. Konkrétní velikost hlavičky (rozšířené výplní ze samých nul na násobek 16 bitů) je pak vyjádřena v položce HLEN.