9.10. TCP – pouzdan tok bajtova¶
TCP, odnosno Transmission Control Protocol, druga je usluga transportnog sloja koja se nalazi povrh IP-a. Dok se UDP najbolje opisuje kao „pošalji paket i nadaj se”, TCP je „otvori vezu između dviju krajnjih točaka i tretiraj je kao dvosmjernu cijev bajtova koje druga strana sigurno primi, redom i točno jednom”. Većina internetskog prometa koristi ga, kao i većina onoga što kamera radi na mreži.
9.10.1. Što TCP dodaje IP-u¶
TCP radi mnogo više od UDP-a. Dodaje:
Vezu. Prije nego što ikakvi podaci poteku, dvije krajnje točke razmjenjuju kratko rukovanje kako bi se dogovorile da razgovaraju. Veza ima stanje – „otvorena”, „poluzatvorena”, „zatvorena” – koje obje strane prate.
Pouzdanu isporuku. Svaki bajt koji pošiljatelj unese primatelj potvrđuje. Sve što nije potvrđeno unutar vremenskog ograničenja šalje se ponovno. Aplikacija nikada ne vidi izgubljeni bajt; vidi kašnjenje dok protokol ponovno šalje.
Isporuku ispravnim redoslijedom. Bajtovi stižu istim redoslijedom kojim su poslani. Čak i ako paketi stignu kod primatelja izvan redoslijeda, TCP ih preuredi prije nego što ih aplikacija pročita.
Kontrolu protoka. Ako je primatelj spor, pošiljatelju se kaže da uspori; veza se prilagođava brzini slabijeg kraja.
Kontrolu zagušenja. Ako mreža u sredini počne ispuštati pakete, pošiljatelj se povuče dok se stanje ne oporavi. To sprječava da bilo koja pojedinačna veza sruši zasićenu vezu.
Sve je to automatsko. Python API koji aplikacija koristi jednostavno je send(bytes) i recv(n); TCP ispod toga obrađuje sve ostalo.
9.10.2. Rukovanje¶
TCP veza otvara se trostrukom razmjenom prije nego što se dopusti prolaz ikakvih podataka:
Trostruko rukovanje. Kada obje strane potvrde, veza je otvorena i podaci mogu teći.¶
Klijent šalje SYN (synchronise) paket s zahtjevom za otvaranje. Poslužitelj odgovara s SYN-ACK (synchronise + acknowledge), prihvaćajući. Klijent šalje završni ACK za potvrdu. Nakon ovog kruga obje se strane slažu da je veza otvorena i sinkronizirale su svoje brojače za praćenje toga koji su bajtovi poslani i primljeni.
Rukovanje košta jednog vremena povratnog putovanja kašnjenja prije nego što prođe prvi koristan bajt. Za lokalne mreže to je milisekunda; za međukontinentalne veze to je otprilike 100 ms. To je glavna cijena TCP-a i razlog zašto je za kratke, jednokratne poruke ponekad bolje umjesto toga koristiti UDP.
9.10.2.1. Rukovanje zatvaranja¶
TCP veze također se zatvaraju razmjenom (FIN od svake strane). Svaki kraj može neovisno zatvoriti svoju polovicu veze; poluzatvoreno stanje u kojem je jedna strana završila slanje, ali druga još razgovara, dopušteno je, premda neuobičajeno. Aplikacija obično samo poziva close() i prepušta protokolu da obradi slijed gašenja.
9.10.3. Što TCP ne jamči¶
Nekoliko stvari za koje se ponekad pretpostavlja da ih TCP radi, ali ih ne radi:
Granice poruka. Aplikacija šalje tok bajtova, ne tok poruka. Dva poziva
send(b"hello")mogu stići kao jedanrecv()odb"hellohello", ili kao dvarecv()-a različitih veličina. Ako aplikacija želi razgraničavanje poruka, mora sama dodati razgraničavanje (novi redak, prefiks duljine, što god). Slanje JSON dokumenata preko TCP-a, na primjer, zahtijeva da svaki dokument bude odvojen novim retkom ili nekom drugom oznakom.Šifriranje. TCP prenosi bajtove koje mu je aplikacija dala, u čistom obliku, cijelim putem. Ako sadržaj mora biti povjerljiv, aplikacija mora omotati vezu u TLS (vidi Šifrirani socketi i TLS).
Autentifikaciju. TCP osigurava da su bajtovi stigli netaknuti. Ne govori ništa o tome tko ih je poslao. Autentifikacija je također briga višeg sloja.
Aktivnost na tihoj vezi. Ako nijedna strana dugo vremena ne šalje podatke, veza je tehnički još otvorena, ali ne može otkriti da se drugi kraj srušio ili nestao. Keepalive ispitivanja mogu se omogućiti na utičnici kako bi se to riješilo kada je to važno.
9.10.4. Kada koristiti TCP¶
TCP je pravi odgovor za gotovo svaki razgovor koji odgovara obliku „klijent otvara vezu prema poslužitelju, razmijene nešto bajtova, veza se zatvara kada su gotovi”. HTTP i HTTPS zahtjevi, SSH sesije, upiti baze podataka, prijenosi datoteka, učitavanja slika – sve preko TCP-a.
Posegnite za UDP-om samo kada razgovor ne odgovara tom obliku: neovisne samostalne poruke gdje je gubitak prihvatljiv, multicast promet, vremenska sinkronizacija, traženja imena ili ekstremni slučajevi osjetljivi na kašnjenje gdje je cijena rukovanja previsoka.
S portovima, UDP-om i TCP-om svima na stolu, priča o transportnom sloju je gotova. Python API koji izlaže oba nalazi se na sljedećoj stranici: Objekti utičnice.