Pāriet uz saturu

TCP

Vikipēdijas lapa

Pārraides vadības protokols jeb protokols TCP (angļu: Transmission Control Protocol)[1] ir viens no galvenajiem interneta protokoliem. TCP ļauj tīkla datoru programmām izveidot savienojumus no vienas uz otru, caur kurām var pārsūtīt datus. Atšķirībā no UDP, šis protokols nodrošina drošu un secīgu datu pārraidi. TCP arī atšķir dažādu programmu savienojuma datus (lietojot portu numurus). TCP ir internetā plašāk lietotais transporta slāņa protokols. Programmas TCP piegādā baitu plūsmas, ko sadala atbilstoša izmēra segmentos (kuru izmēru parasti nosaka kanāla slāņa MTU (maximum transmission unit)). Iegūtās paketes TCP tālāk piegādā IP nosūtīšanai caur tīklu. TCP pārbauda, vai paketes nav pazaudētas katrai paketei pieliekot sākotnējo numuru, kuru arī lieto lai pārliecinātos, ka dati ir piegādāti sākotnējā secībā. Par sekmīgi saņemtajām paketēm, TCP sūta atpakaļ apstiprinājumus. Ja sūtītājs laikus (kamēr nav iestājusies noildze) nesaņem apstiprinājumu, paketi uzskata par pazaudētu un nosūta vēlreiz. TCP pārbauda vai paketes dati nav bojāti, lietojot kontrolsummu.

TCP nav optimizēts lietošanai bezvadu tīklos. Pieņem, ka visi pakešu zudumi rodas nepietiekamas datu kanāla caurlaidības dēļ. Bezvadu tīklos pakešu zudumi rodas lielākoties citu iemeslu dēļ. Tas samazina TCP ātrumu šādos apstākļos, jo pēc katras pazaudētās paketes TCP samazina sūtīšanas ātrumu.

Lai arī TCP ir internetā visplašāk lietotais transporta slāņa protokols, ir daži pielietojumi, kur tas nav piemērots (tur lieto UDP):

  • TCP nodrošina secīgu datu pārraidi, ja daļa datu pazūd, tos pārsūta vēlreiz un tas rada aizķeršanos. Dažiem pielietojumiem (spēlēm, VoIP) šāda aizķeršanās ir nevēlamāka kā datu zudumi.
  • TCP ir samērā sarežģīts protokols, lai atvērtu savienojumu vien vajag 3 paketes (no kurām neviena nenes derīgos datus). Vēl, TCP darbināšanai vajag vairāk brīvpiekļuves atmiņas nekā UDP (tam nav nozīmes datoriem, bet var būt nozīme PXE).

Protokola darbība

[labot šo sadaļu | labot pirmkodu]

Atšķirībā no UDP, kas var sākt sūtīt datus bez jebkādas iepriekšējas sagatavošanās, TCP nodrošina savienojumus, kurus vispirms vajag izveidot, pirms var sākt sūtīt datus. TCP savienojumiem ir 3 dzīves stadijas:

  • Izveidošana (savienojuma atvēršana)
  • Datu pārraide (savienojums ir atvērts)
  • Aizvēršana (savienojuma aizvēršana)

Savienojuma galapunkti datorā ir soketi (sockets). TCP tiem var būt 11 stāvokļi:

  1. LISTEN - šajā stāvoklī sokets gaida savienojuma pieprasījumu no ārpuses, šo lieto visi TCP serveri
  2. SYN-SENT - šeit nupat no šejienes ir nosūtīts savienojuma pieprasījums uz ārēju serveri un sokets gaida atbildi
  3. SYN-RECEIVED - sokets nupat ir nosūtījis SYN paketi un gaida saņemšanas apstiprinājumu (ACK) (šo lieto TCP serveri. Šajā stadijā nonāk LISTEN savienojums pēc savienojuma pieprasījuma saņemšanas un apstiprinājuma nosūtīšanas)
  4. ESTABLISHED - caur šo soketu ir atvērts strādājošs savienojums, caur kuru var pārsūtīt datus
  5. FIN-WAIT1 - savienojuma aiztaisīšanas stadija, no šejienes ir nosūtīts savienojuma aiztaisīšanas pieprasījums uz otru galu un šis sokets gaida atbildi
  6. FIN-WAIT2 - savienojuma aiztaisīšanas stadija, saņēmis savienojuma aiztaisīšanas pieprasījumu (no otra gala) un gaida pēdējo ACK
  7. CLOSE-WAIT - savienojuma aiztaisīšanas stadija, otrs gals pieprasīja aiztaisīt savienojumu, šis aizsūtīja apstiprinājumu un nonāca te
  8. CLOSING - savienojuma aiztaisīšanas stadija, abi gali mēģināja aiztaisīt savienojumu vienlaicīgi
  9. LAST-ACK - savienojuma aiztaisīšanas stadija, gaida, kamēr pienāks pēdējās šim savienojumam piederošās paketes
  10. TIME-WAIT - savienojuma aiztaisīšanas stadija, šajā stadijā sokets nonāk pēc savienojuma aiztaisīšanas pieprasījuma nosūtīšanas uz otru galu, te sokets gaida apstiprinājumu tam pieprasījumam. Saskaņā ar rfc793, šajā stadijā sokets var būt ne ilgāk kā 4 minūtes.
  11. CLOSED - šajā stadijā savienojums ir aiztaisīts, te atrodas vai nu pirms savienojuma atvēršanas (vienalga, aktīvās vai pasīvās) vai arī pēc savienojuma aiztaisīšanas.

Savienojuma atvēršana

[labot šo sadaļu | labot pirmkodu]

Lai klients varētu pieslēgties serverim, tur ir jābūt atvērtam portam (passive open). Pēc tam klients uz turieni var sūtīt savienojuma pieprasījumu. TCP, tāpat kā UDP ir klienta-servera bāzēts protokols. Visas TCP implementācijas spēj darboties gan kā klients, gan kā serveris. Klients atver savienojumu uz serveri. Savienojumi sastāv no diviem vienvirziena datu kanāliem.

  1. Klients sūta savienojuma atvēršanas pieprasījumu SYN (synchronize, active open) uz serveri
  2. Serveris atbild ar SYN un ACK (acknowledgment - savienojuma izveidošanas apstiprinājums)
  3. Klients atbild ar ACK un pēc tam izveidojas savienojums starp klientu un serveri.

Piemērs:

  1. Klients aizsūta serverim SYN paketi (ar aktīvu SYN karodziņu). Visas SYN paketes satur numuru (sequence number), tas ir 32 bitu lauks TCP paketes hederī, sākumam parasti paņem nejaušu skaitli. Šim piemēram pieņemam x.
  2. Otrs gals (serveris) saņem paketi un pieraksta tās numuru (sequence number), kas šajā gadījumā ir x un nosūta atpakaļ paketi ar SYN un ACK (aktīvi SYN un ACK karodziņi paketes hederī). ACK ir 32 bitu lauks paketes hederī, tas satur nākamās sagaidāmās paketes numuru, kas šajā gadījumā ir x+1, ar šo paketi vienlaikus tiek atvērts pretējā virziena savienojums, kuras vajadzībām lieto sākotnējo numuru (sequence number) y.
  3. Sākotnējais dators (klients) aizsūta ACK paketi, kurai ACK laukā ir y+1. Ar to abu virzienu savienojumi ir sasinhronizēti.

Galvenās TCP atšķirības no UDP ir:

  • secīga datu pārraide,
  • atkārtota pazaudēto pakešu nosūtīšana,
  • ja vienas un tās pašas paketes pienāk vairākkārtīgi, tad liekos eksemplārus izmet,
  • ja paketei neatbilst kontrolsumma, to arī izmet (un gaida kad atsūtīs jaunu, labāku),
  • plūsmas vadība (congestion control un flow control)

Atverot savienojumu, abi datori apmainās ar numuriem (sequence numbers), kas var būt jebkādi skaitļi. Šis skaitlis apraksta no attiecīgā datora nosūtīto baitu skaitu, katrai nākamajai paketei tas palielinās par iepriekšējā paketē nosūtīto baitu skaitu. Paketes apstiprinājumi (ACK) satur nākamo sagaidāmo kārtas numuru (pēdējais saņemtais baits +1). Ja paketes pazūd, pārsūta visu kopš pēdējā veiksmīgi apstriprinātā baita. Kārtas numuri un ACK nodrošina dubulto pakešu identifikāciju (tām tie būs vienādi), pazaudēto pakešu atkārtotu nosūtīšanu (ja sūtītājs laicīgi nesaņem ACK tas uzskata, ka pakete ir pazaudēta un nosūta vēlreiz) un secīgu datu pārraidi numuri (sequence numbers) atbilst nosūtīto baitu skaitam, ja saņem mazāk baitu kā būtu jābūt pēc tiem numuriem ir skaidrs, ka pa vidu kaut kā trūkst.

Lai pārliecinātos, ka dati pārsūtīšanas laikā nav bojāti, lieto 16 bitu kontrolsummu.

Plūsmas vadība (congestion control un flow control). Šīm vajadzībām TCP lieto vairākus mehānismus, kuri regulē nosūtīšanas ātrumu. Sūtītāji tam lieto saņemtos un nesaņemtos ACK. Ja saņemts ACK, uzskata, ka dati ir aizgājuši veiksmīgi, ja nesaņem - ka pazaudēti. Par galveno datu pazaudēšanas iemeslu uzskata savienojuma nepietiekamo datu caurlaidību (tādēļ maršrutētāji ir bijuši spiesti paketes izmest).

Pārraides logs (transmit window) ir ienākošo datu bufera izmērs, tas ir maksimālais datu daudzums, kādu var nosūtīt sūtītājs nesaņemot ACK. ACK paketes satur datus par atlikušo pārraides loga vietu. Ja sūtītājs saņem paziņojumu, ka pieejamais pārraides loga izmērs ir 0, tas pārtrauc sūtīt un gaida. Lai novērstu situāciju, ja pakete, kas ziņoja par jaunu brīvo vietu pārraides logā, ir pazaudēta un sakari iestrēgst, sūtītājs ik pa laikam nosūta mazu paketi, kurai atbilstošais ACK satur pēdējo pārraides loga (transmit window) izmēru.

UDP īpatnības ir:

  • nav secīga datu pārraide (ja kāda pakete pienāk vēlāk, tā netiek sakārtota pēc kārtas numuriem),
  • netiek pārsūtītas pazaudētās paketes (ja kāda pakete ir pazudusi un nav saņemta, netiek sūtīts pieprasījums pārsūtīt paketi),
  • ja viena un tā pati pakete pienāk divkārt, liekos eksemplārus neizmet,
  • nav vajadzīga datu pārraides uzstādīšana (paketes var tikt nosūtītas bez 3 pakāpju savienojuma izveidošanas kā tas ir ar TCP)

Šo protokolu galvenokārt izmanto DNS vai arī video un audio. UDP paketes tiek pārsūtītas ātrāk. Skatoties video vai klausoties mūziku, ir neiespējami pamanīt, ja kāda pakete ir pazudusi vai pienākusi vēlāk.

Savienojuma pārtraukšana

[labot šo sadaļu | labot pirmkodu]

Savienojuma pārtraukšanai parasti nosūta 4 paketes. Viens gals sāk savienojuma beigšanu nosūtot FIN paketi, kuru otrs gals apstiprina ar ACK. Lai slēgtu otru savienojuma pusi, vajag vēl divas tādas pašas paketes pretējā virzienā. Dažreiz pirmo ACK apvieno ar otro FIN, tad var iztikt ar 3 paketēm. Ja pazūd sakari (nevienai nosūtītajai paketei nepienāk ACK), tad arī savienojums tiek pārtraukts.

TCP protokolā, tāpat kā UDP protokolā ir 65535 porti. TCP lieto portu numurus, lai identificētu sūtošās un saņemošās programmas savienojuma galapunktos. Katram TCP savienojuma galam ir piesaistīts 16 bitu skaitlis - porta numurs, pēc kura identificē ienākošās paketes. Noteiktiem serveriem parasti piesaista noteiktus portu numurus (piem. http - 80, smtp - 25, ftp - 21), kurus lieto kā noklusēto vērtību.

TCP segmentu struktūra

[labot šo sadaļu | labot pirmkodu]

TCP sadala ienākošo datu plūsmu segmentos (paketēs), kuras tālāk ievieto IP paketēs nosūtīšanai tālāk. TCP segmentu veido divas daļas - hederis un dati. TCP hederim ir 12 lauki, no kuriem 10 ir obligāti.

TCP Header
+ Biti 0—3 4—7 8—15 16—31
0 Sūtītāja ports (Source port) Saņēmēja ports (Destination port)
32 Paketes kārtas numurs (Sequence number)
64 Apstiprinājuma numurs (Acknowledgment number)
96 Datu nobīde (Data offset) Rezervēts Karodziņi (Flags) Logs (Window)
128 Kontrolsumma Steidzamais norādījums (Urgent pointer)
160 Iespējas (Options)
160/192+  
Dati (Data)
 
  • Sūtītāja ports - identificē portu, no kura segments ir ticis nosūtīts
  • Saņēmēja ports - identificē portu, uz kuru segmentu sūta
  • Paketes kārtas numurs - paketes numurs, tam ir divas nozīmes:
    • Ja SYN ir aktīvs, tad tas ir sākotnējais numurs un pirmajam datu baitam atbilst šis skaitlis +1
    • Ja SYN nav aktīvs, tad tas atbilst pirmajam datu baitam
  • Apstiprinājuma numurs - ja ACK ir aktīvs, tad šī lauka vērtība ir sūtītāja sagaidāmais nākamais sequence number
  • Datu nobīde - norāda TCP hedera izmēru 4 baitos un attiecīgi nobīdi līdz datu sākumam. Minimālais izmērs ir 5 (maksimālais - 15).
  • Rezervēts - šis lauks ir rezervēts nākotnes vajadzībām un tam ir jābūt 0.
  • Karodziņi - (8) 1 bita lauki:
    • CWR - (Congestion window reduced) šo uzliek sūtītāji, lai norādītu, ka saņēmuši ACK ar aktīvu ECE
    • ECE - (ECN-echo) norāda, ka otra gala ierīce spēj darboties ar ECN protokolu (TCP paplašinājums)
    • URG - (Urgent pointer) norāda, ka pakete ir jānosūta steidzami
    • ACK - (Acknowledgement number) norāda, ka lauks satur kaut kādu vērtību (pakete satur apstiprinājumu kādai no iepriekšējām paketēm)
    • PSH - (Push) pakete TCP līmenī tiek pārraidīta ātrāk
    • RST - (Reset) aiztaisa savienojumu piespiedu kārtā, šo lieto arī lai atteiktu savienojumu
    • SYN - (Synchronize) sinhronizē - saskaņo kārtas numurus starp klientu un serveri atverot savienojumu
    • FIN - (Finalize) no sūtītāja vairāk datu nebūs (tiek sūtīta aizverot savienojumu)
  • Logs - to izmanto vēl nepārsūtītām paketēm. Tas ļauj abām pusēm sekot līdz pakešu plūsmai, lai precīzi zinātu, ka visas paketes ir saņemtas pareizi un nosūtītu apstiprinājumu pirms sūtīt jaunu paketi.
  • Kontrolsumma - 16 bitu kontrolsumma lai pārbaudītu vai hederī un datos nav kļūdu. To aprēķina pēc līdzīga algoritma kā IP kontrolsummu.
  • Steidzamais norādījums - norāda, ka pakete ir jāpārsūta nekavējoties, kaut arī šis logs tiek izmantots reti.
  • Iespējas - izmanto, lai noskaidrotu datu apstrādes iespējas datu saņēmējam un datu sūtītājam TCP līmenī. Piemēram, ja TCP līmenis ir spējīgs apstrādāt datus, kuru izmērs nepārsniedz norādīto maksimumu, sistēma par tādiem ierobežojumiem ziņos laukā iespējas.
  • Dati - tie ir pārsūtāmie dati un nav daļa no hedera.

Kontrolsummu aprēķina datiem, visam TCP hederim (aizvietojot kontrolsummas lauku ar nullēm) un daļai IP hedera, kas satur abas adreses, paketes garuma lauku (16bit) protokola lauku (8bit)(identificē TCP un ir 6) un tukšu 8 bit lauku. (pēdējie 3 pretējā secībā). IPv6 gadījumā paketes garuma lauks nāk tieši aiz adresēm un ir 32bit, pēc tam ir 24bit nulles un aiz tām ir next header lauks kas identificē TCP un ir 8bit.