9.10. TCP – spolehlivý proud bajtů¶
TCP, neboli Transmission Control Protocol, je druhá služba transportní vrstvy postavená nad IP. Zatímco UDP lze nejlépe popsat jako „odešli paket a doufej“, TCP znamená „otevři spojení mezi dvěma koncovými body a zacházej s ním jako s obousměrnou rourou bajtů, které druhá strana zaručeně dostane, ve správném pořadí a právě jednou“. Většina internetového provozu jej využívá a stejně tak většina toho, co kamera dělá v síti.
9.10.1. Co TCP přidává k IP¶
TCP toho dělá mnohem víc než UDP. Přidává:
Spojení. Než začnou téct jakákoli data, oba koncové body si vymění krátké navázání spojení (handshake), aby se dohodly, že spolu komunikují. Spojení má stav – „otevřené“, „napůl uzavřené“, „uzavřené“ – který obě strany sledují.
Spolehlivé doručení. Každý bajt, který odesílatel vloží, je příjemcem potvrzen. Cokoli, co není potvrzeno do vypršení časového limitu, se odešle znovu. Aplikace nikdy neuvidí ztracený bajt; uvidí pouze zpoždění, zatímco protokol data znovu odesílá.
Doručení ve správném pořadí. Bajty dorazí ve stejném pořadí, v jakém byly odeslány. I když pakety dorazí k příjemci mimo pořadí, TCP je před přečtením aplikací seřadí zpět.
Řízení toku. Pokud je příjemce pomalý, odesílatel dostane pokyn zpomalit; spojení se přizpůsobí rychlosti slabšího konce.
Řízení zahlcení. Pokud síť uprostřed začne zahazovat pakety, odesílatel ubere, dokud se situace neuklidní. Tím se zabrání tomu, aby jedno jediné spojení shodilo přetíženou linku.
Toto vše probíhá automaticky. Python API, které aplikace používá, je jednoduše send(bytes) a recv(n); TCP se postará o všechno ostatní pod kapotou.
9.10.2. Navázání spojení (handshake)¶
TCP spojení se otevírá trojcestnou výměnou, než smí projít jakákoli data:
Trojcestné navázání spojení. Jakmile obě strany potvrdí, je spojení otevřené a data mohou téct.¶
Klient odešle paket SYN (synchronizace) s žádostí o otevření. Server odpoví paketem SYN-ACK (synchronizace + potvrzení), čímž akceptuje. Klient odešle závěrečný ACK na potvrzení. Po tomto kole obě strany souhlasí, že je spojení otevřené, a synchronizovaly své čítače pro sledování toho, které bajty byly odeslány a přijaty.
Navázání spojení stojí jeden round-trip-time latence, než projde první užitečný bajt. Pro lokální sítě je to milisekunda; pro mezikontinentální spojení zhruba 100 ms. To je hlavní cena TCP a důvod, proč jsou krátké, jednorázové zprávy někdy lépe obsloužené pomocí UDP.
9.10.2.1. Uzavírací navázání spojení¶
TCP spojení se také uzavírají výměnou (paket FIN od každé strany). Kterýkoli konec může nezávisle uzavřít svou polovinu spojení; stav napůl uzavřeno, kdy jedna strana dokončila odesílání, ale druhá stále komunikuje, je legální, byť neobvyklý. Aplikace obvykle jen zavolá close() a nechá protokol obsloužit sekvenci ukončení.
9.10.3. Co TCP nezaručuje¶
Pár věcí, o kterých se někdy předpokládá, že je TCP dělá, ale nedělá:
Hranice zpráv. Aplikace odesílá proud bajtů, nikoli proud zpráv. Dvě volání
send(b"hello")mohou dorazit jako jednorecv()s obsahemb"hellohello", nebo jako dvěrecv()různých velikostí. Pokud aplikace chce rámcování zpráv, musí si rámcování přidat sama (nový řádek, délkový prefix, cokoli). Odesílání JSON dokumentů přes TCP například vyžaduje, aby byl každý dokument oddělen novým řádkem nebo jiným oddělovačem.Šifrování. TCP přenáší bajty, které mu aplikace předala, v otevřené podobě, celou cestu. Pokud má být obsah důvěrný, aplikace musí spojení zabalit do TLS (viz Šifrované sockety a TLS).
Autentizace. TCP zajišťuje, že bajty dorazily neporušené. Neříká nic o tom, kdo je odeslal. Autentizace je rovněž záležitostí vyšší vrstvy.
Životnost na nečinném spojení. Pokud ani jedna strana po dlouhou dobu neodešle data, spojení je technicky stále otevřené, ale nedokáže rozpoznat, že druhý konec spadl nebo zmizel. Pokud na tom záleží, lze na soketu povolit sondy keepalive, které to vyřeší.
9.10.4. Kdy použít TCP¶
TCP je správná odpověď téměř pro každou konverzaci, která zapadá do tvaru „klient otevře spojení k serveru, vymění si nějaké bajty a po dokončení se spojení uzavře“. Požadavky HTTP a HTTPS, SSH relace, databázové dotazy, přenosy souborů, nahrávání obrázků – vše přes TCP.
Po UDP sáhněte jen tehdy, když konverzace do tohoto tvaru nezapadá: nezávislé samostatné zprávy, kde je ztráta přijatelná, multicastový provoz, synchronizace času, vyhledávání jmen nebo extrémně na latenci citlivé případy, kde je cena navázání spojení neúnosná.
S porty, UDP a TCP na stole je příběh transportní vrstvy hotový. Python API, které oba zpřístupňuje, je na další stránce: Objekty socketů.