Stabilirea și întreruperea unei conexiuni TCP. Strat de transport Strângere de mână în trei căi tcp

Stabilirea unei conexiuni TCP

În protocolul TCP, conexiunile sunt stabilite folosind „ strângere de mână triplă", descris în secțiunea „Stabilirea unei conexiuni”. Pentru a stabili o conexiune, o parte (cum ar fi serverul) așteaptă pasiv o conexiune de intrare executând primitivele LISTEN și ACCEPT, fie specificând o anumită sursă, fie nespecificând una.

Cealaltă parte (cum ar fi clientul) emite o primitivă CONNECT, specificând adresa IP și portul la care dorește să se conecteze, dimensiunea maximă a segmentului TCP și, opțional, unele date de utilizator (cum ar fi o parolă). Primitiva CONNECT trimite un segment TCP cu bitul SYN setat și bitul ACK șters și așteaptă un răspuns.

Când acest segment ajunge la destinație, entitatea TCP verifică dacă vreun proces a executat primitiva LISTEN, specificând ca parametru același port conținut în câmpul Destination Port. Dacă nu există un astfel de proces, acesta răspunde prin trimiterea unui segment cu bitul RST setat pentru a refuza conexiunea.

Dacă vreun proces ascultă pe orice port, atunci segmentul TCP de intrare este transmis procesului respectiv. Acesta din urmă poate accepta conexiunea sau o poate refuza. Dacă procesul acceptă conexiunea, trimite o confirmare ca răspuns. Secvența de segmente TCP trimise în cazul normal (Fig. a) Rețineți că un segment cu setul de biți SYN ocupă 1 octet de spațiu de numere de secvență, ceea ce evită ambiguitatea în confirmările lor.

Dacă două gazde încearcă simultan să stabilească o conexiune între ele, atunci succesiunea evenimentelor care au loc va corespunde cu Fig. b. Ca rezultat, se va stabili o singură conexiune, nu două, deoarece perechea de puncte finale identifică în mod unic conexiunea. Adică, dacă ambele conexiuni încearcă să se identifice folosind perechea (x, y), se face o singură intrare în tabel pentru (x, y).

Valoarea inițială a numărului secvenței conexiunii nu este zero din motivele discutate mai sus. Se folosește un circuit bazat pe un temporizator, schimbându-și starea la fiecare 4 μs. Pentru o mai mare fiabilitate, gazda după o eroare i se interzice repornirea mai devreme decât după ce durata maximă de viață a pachetului a trecut. Acest lucru asigură că niciun pachet de la conexiunile anterioare nu plutește pe Internet.

Scăderea conexiunii TCP

Deși conexiunile TCP sunt full-duplex, pentru a înțelege cum sunt eliberate, este mai bine să ne gândim la ele ca perechi de conexiuni simplex. Fiecare conexiune simplex se întrerupe independent de partenerul său. Pentru a închide conexiunea, fiecare parte poate trimite un segment TCP cu bitul FIN setat la unu, indicând că nu mai are date de trimis. Când acest segment TCP primește o confirmare, această direcție de transmisie este închisă. Cu toate acestea, datele pot continua să curgă la nesfârșit în direcția opusă. Conexiunea este întreruptă când ambele direcții sunt închise. De obicei, sunt necesare patru segmente TCP pentru a închide o conexiune: unul cu bitul FIN și unul cu bitul ACK în fiecare direcție. Primul bit ACK și al doilea bit FIN pot fi de asemenea conținute într-un segment TCP, ceea ce va reduce numărul de segmente la trei.

Ca în conversatie telefonica Când ambele părți își pot lua rămas bun și închide în același timp, ambele capete ale conexiunii TCP pot trimite mesaje FIN în același timp. Amândoi primesc mulțumirile obișnuite și conexiunea este închisă. În esență, nu există nicio diferență între deconectările simultane și secvențiale.

Pentru a evita problema a două armate, se folosesc cronometre. Dacă un răspuns la un segment FIN trimis nu ajunge în două intervale maxime de viață a pachetului, expeditorul închide conexiunea. Cealaltă parte va observa în cele din urmă că nimeni nu răspunde și se va deconecta. Deși această soluție nu este ideală, având în vedere imposibilitatea idealului, trebuie să folosim ceea ce avem. În practică, problemele apar destul de rar.

Controlul transmisiei TCP

După cum am menționat mai devreme, gestionarea ferestrelor TCP nu este direct legată de confirmări, așa cum se întâmplă în majoritatea protocoalelor de transfer de date. De exemplu, să presupunem că destinatarul are un buffer de 4096 de octeți. Dacă expeditorul transmite un segment de 2048 de octeți care este primit cu succes de către destinatar, atunci destinatarul confirmă primirea acestuia. Totuși, acest lucru lasă receptorului doar 2048 de octeți de spațiu liber în buffer (până când aplicația preia unele date din buffer), pe care le raportează expeditorului, indicând dimensiunea corespunzătoare a ferestrei (2048) și numărul următorului octet așteptat.

Expeditorul trimite apoi alți 2048 de octeți, care sunt confirmați, dar dimensiunea ferestrei este declarată a fi 0. Expeditorul trebuie să nu mai transmită până când gazda care primește eliberează spațiu în buffer și crește dimensiunea ferestrei.

Cu o dimensiune a ferestrei de zero, expeditorul nu poate trimite segmente, decât în ​​două cazuri. În primul rând, este permisă trimiterea de date urgente, de exemplu, astfel încât un utilizator să poată ucide un proces care rulează pe o mașină de la distanță. În al doilea rând, expeditorul poate trimite un segment de 1 octet cerând receptorului să repete informații despre dimensiunea ferestrei și următorul octet așteptat. Standardul TCP oferă în mod explicit această caracteristică pentru a preveni blocajele în cazul în care anunțul de dimensiunea ferestrei este pierdut.

Expeditorii nu sunt obligați să transmită datele imediat, deoarece acestea provin din aplicație. De asemenea, nimeni nu cere destinatarilor să trimită confirmări cât mai curând posibil. De exemplu, o entitate TCP, după ce a primit primii 2 KB de date de la o aplicație și știind că dimensiunea ferestrei disponibile este de 4 KB, ar fi perfect să stocheze pur și simplu datele primite într-un buffer până când ajung încă 2 KB de date. trimite imediat un segment cu 4 KB de sarcină utilă. Această discreție poate fi folosită pentru a îmbunătăți performanța.

Luați în considerare o conexiune TELNET cu un editor interactiv care răspunde la fiecare apăsare a tastei. ÎN cel mai rău caz Când caracterul ajunge la entitatea TCP care trimite, acesta creează un segment TCP de 21 de octeți și îl transmite stratului IP, care la rândul său trimite o datagramă IP de 41 de octeți.

La capătul de recepție, entitatea TCP răspunde imediat cu o confirmare de 40 de octeți (antet TCP de 20 de octeți și antet IP de 20 de octeți). Apoi, când editorul citește acel octet din buffer, entitatea TCP va trimite o actualizare cu privire la dimensiunea bufferului, mutând fereastra cu 1 octet la dreapta. Mărimea acestui pachet este, de asemenea, de 40 de octeți. În cele din urmă, când editorul a procesat acest caracter, trimite înapoi un ecou, ​​transmis într-un pachet de 41 de octeți. În total, pentru fiecare caracter introdus de la tastatură sunt trimise patru pachete cu o dimensiune totală de 162 de octeți. În condiții de deficit de capacitate de linie, această metodă de operare este nedorită.

Pentru a îmbunătăți situația, multe implementări TCP întârzie confirmările și actualizările dimensiunii ferestrelor cu 500 ms în speranța de a obține date suplimentare cu care să trimită confirmarea într-un singur pachet. Dacă editorul reușește să ecou în 500 ms, unui utilizator de la distanță Va trebui trimis doar un pachet de 41 de octeți, reducând astfel sarcina rețelei la jumătate.

Deși această metodă de întârziere reduce încărcarea rețelei, eficiența rețelei expeditorului rămâne scăzută, deoarece fiecare octet este trimis într-un pachet separat de 41 de octeți. O metodă care îmbunătățește eficiența este cunoscută sub numele de algoritmul lui Nagle (Nagle, 1984). Propunerea lui Nagl sună destul de simplă: dacă datele sosesc la expeditor câte un octet, expeditorul pur și simplu transmite primul octet și păstrează în tampon restul până când este primită o confirmare a primului octet. După aceasta, puteți trimite toate caracterele acumulate în buffer ca un singur segment TCP și puteți începe din nou tamponarea până când primiți confirmarea caracterelor trimise. Dacă utilizatorul introduce caractere rapid și rețeaua este lentă, atunci un număr semnificativ de caractere va fi transmis în fiecare segment, reducând astfel în mod semnificativ încărcarea rețelei. În plus, acest algoritm permite trimiterea unui nou pachet chiar dacă numărul de caractere din buffer depășește jumătate din dimensiunea ferestrei sau dimensiunea maximă a segmentului.

Algoritmul lui Nagl este utilizat pe scară largă de diverse implementări Protocolul TCP, totuși, uneori există situații în care este mai bine să-l dezactivați. În special, atunci când lucrezi aplicații X-Windows pe Internet, informațiile despre mișcările mouse-ului sunt trimise la un computer de la distanță. (X-Window este sistemul de gestionare a ferestrelor pentru majoritatea sistemelor de operare de tip UNIX). Dacă salvați aceste date pentru transferul în lot, cursorul se va mișca sacadat cu pauze lungi, drept urmare va fi foarte dificil, aproape imposibil, să utilizați programul.

O altă problemă care poate degrada semnificativ performanța TCP este cunoscută sub numele de sindromul ferestrei stupide (Clark, 1982). Esența problemei este că datele sunt trimise de entitatea TCP în blocuri mari, dar partea de recepție a aplicației interactive le citește caracter cu caracter.

Să ne uităm la un exemplu - starea inițială este următoarea: tamponul TCP al părții de recepție este plin, iar expeditorul știe acest lucru (adică dimensiunea ferestrei sale este 0). Aplicația interactivă citește apoi un caracter din fluxul TCP. Entitatea TCP de primire informează cu bucurie expeditorul că dimensiunea ferestrei a crescut și că acum poate trimite 1 octet. Expeditorul se supune și trimite 1 octet. Buffer-ul este din nou plin, ceea ce receptorul îl notifică trimițând o confirmare pentru un segment de 1 octet cu dimensiunea ferestrei zero. Și asta poate continua pentru totdeauna.

David Clark a propus să împiedice capătul de recepție să trimită informații despre dimensiunea ferestrei de un octet. În schimb, destinatarul trebuie să aștepte până când există o cantitate semnificativă de spațiu liber în buffer. În special, receptorul TREBUIE să trimită informații despre noua dimensiune a ferestrei până când nu poate accepta segmentul de dimensiune maximă pe care l-a anunțat la stabilirea conexiunii, sau tamponul său este cel puțin pe jumătate liber.

În plus, expeditorul însuși poate contribui la îmbunătățirea eficienței trimiterii, nu trimițând segmente prea mici. În schimb, trebuie să aștepte până când dimensiunea ferestrei este suficient de mare pentru a-i permite să trimită un segment complet sau cel puțin egal cu jumătate din dimensiunea buffer-ului receptorului. (Expeditorul poate estima această dimensiune dintr-o secvență de mesaje cu dimensiunea ferestrei pe care le-a primit anterior.)

În problema scăpării de sindromul ferestrei stupide, algoritmul lui Nagl și soluția lui Clark se completează reciproc. Nagl încerca să rezolve problema unei aplicații care furnizează date unei entități TCP caracter cu caracter. Clark a încercat să rezolve problema unei aplicații care primește date caracter cu caracter de la TCP. Ambele soluții sunt bune și pot funcționa simultan. Esența lor este să nu trimită sau să ceară transmiterea datelor în porțiuni prea mici.

Entitatea de recepție TCP poate merge și mai departe în îmbunătățirea performanței prin simpla actualizare a informațiilor despre dimensiunea ferestrei în bucăți mari. La fel ca entitatea TCP care trimite, poate, de asemenea, să tamponeze datele și să blocheze o solicitare READ de la o aplicație până când are o cantitate mare de date. Acest lucru reduce numărul de apeluri către entitatea TCP și, prin urmare, reduce supraîncărcarea. Desigur, această abordare mărește timpul de răspuns, dar pentru aplicațiile non-interactive, precum transferul de fișiere, reducerea timpului petrecut pe întreaga operațiune este mult mai importantă decât creșterea timpului de răspuns pentru solicitările individuale.

O altă problemă a destinatarului o reprezintă segmentele primite în ordine greșită. Acestea pot fi păstrate sau eliminate la discreția destinatarului. Desigur, o confirmare poate fi trimisă numai dacă au fost primite toate datele până la octetul care este confirmat. Dacă receptorul primește segmentele O, 1, 2, 4, 5, 6 și 7, acesta poate confirma primirea datelor până la ultimul octet al segmentului 2. Când expeditorul expiră, va transmite din nou segmentul 3. Dacă receptorul are segmentele de la 4 la 7 în buffer până la sosirea segmentului 3, acesta poate confirma primirea tuturor octeților până la ultimul octet al segmentului 7.

- 1

Funcțiile stratului de transport

  • oferă o conexiune logică între aplicații;
  • implementează transmisii fiabile de date;
  • oferă controlul vitezei de transfer de date.

Prize

Priză(socket) este o structură de date care identifică o conexiune de rețea.

De ce sunt necesare prize? Serverul (programul) poate suporta simultan mai multe conexiuni TCP cu alte computere care folosesc același camera standard port. Cum să implementezi asta? Puteți atribui această sarcină unui programator. Lăsați-l să selecteze pachetele din stratul de rețea pentru primire tampon, să uite de la cine au fost trimise și să răspundă în consecință. Dar puteți face toate acestea mai convenabile.

Fiecare conexiune trebuie să aibă propriul fir asociat cu ea, în care să poată fi scrise informații și din care să poată fi citite. Fiecare flux are propria sa adresă IP computer la distanțăși portul dvs. de pe computerul de la distanță. Vom numi structura de date corespunzătoare fiecărui astfel de flux un socket (socket). Astfel, serverul poate fi comparat cu o priză multiplă cu o grămadă de prize la care sunt conectați clienții.

Dacă faceți acest lucru, atunci în loc să sortați o grămadă de pachete diferite din tamponul de primire a stratului de rețea, serverul va citi din fluxuri, fiecare dintre acestea corespunzând unui client diferit. Datele de la clienți nu vor fi îngrămădite, ci vor fi distribuite în fluxurile de socket. Responsabilitatea pentru o astfel de distribuție nu revine programatorului, ci driverului stratului de transport al sistemului de operare.

Prizele au fost dezvoltate la Universitatea din California din Berkeley și au devenit standardul de facto spre deosebire de OSI TLI (Transport Layer Interface).

Informații istorice. divizarea UNIX

BSD UNIX, creat la Universitatea din Berkeley, și-a început istoria în 1978. Autorul BSD a fost Bill Joy. La începutul anilor 1980, AT&T, care deținea Bell Labs, a recunoscut valoarea UNIX și a început să creeze o versiune comercială a UNIX. Un motiv important pentru divizarea UNIX a fost implementarea stivei de protocoale TCP/IP în 1980. Înainte de aceasta, comunicarea de la mașină la mașină în UNIX era la început - cea mai importantă metodă de comunicare era UUCP (un mijloc de copiere a fișierelor dintr-un sistem UNIX în altul, care lucra inițial la retelele telefonice folosind modemuri).

Aceşti doi sisteme de operare implementat 2 interfață diferită programare aplicații de rețea: Socket-uri Berkley (TCP/IP) și interfață pentru stratul de transport TLI (OSI ISO). Interfața socket-urilor Berkley a fost dezvoltată la Universitatea din Berkeley și a folosit stiva de protocoale TCP/IP dezvoltată acolo. TLI a fost creat de AT&T conform definiției stratului de transport a modelului OSI. Inițial, nu a implementat TCP/IP sau alte protocoale de rețea, dar implementări similare au fost furnizate de terți. Acest lucru, precum și alte considerente (în mare parte cele de piață), au determinat divizarea finală între cele două ramuri ale UNIX - BSD (Berkeley University) și System V ( versiune comercială de la AT&T). Ulterior, multe companii, având licență System V de la AT&T, și-au dezvoltat propriile versiuni comerciale de UNIX, cum ar fi AIX, HP-UX, IRIX, Solaris.

Primitive socket

PRIZĂ creați un nou soclu (gol).
LEGA serverul își conectează adresa locala(port) cu priză
ASCULTA serverul alocă memorie pentru coada de conexiune client (TCP)
ACCEPTA serverul așteaptă să se conecteze un client sau acceptă prima conexiune din coadă (TCP). Pentru a bloca așteptarea conexiunilor de intrare, serverul execută primitiva ACCEPT. La primirea unei cereri de conectare, modulul de transport al sistemului de operare creează un nou socket cu aceleași proprietăți ca și socket-ul original și returnează un handle de fișier pentru acesta. Serverul poate deschide apoi un proces sau un fir pentru a gestiona conexiunea pentru noul soclu și, în paralel, poate aștepta următoarea conexiune pentru soclul original
CONECTAȚI client solicită conexiune (TCP)
SEND / SEND_TO trimite date (TCP/UDP)
PRIMIȚI / PRIMIȚI_DIN primiți date (TCP/UDP)
DECONECTA cerere de deconectare (TCP)

Multiplexare și demultiplexare

Multiplexarea- colectarea mesajelor de la socket-urile tuturor aplicațiilor și adăugarea antetelor.

Demultiplexarea- distribuția datelor primite între socket-uri.

Pentru UDP, socket-ul necesar este determinat de numărul portului destinatarului, pentru TCP - de numărul portului destinatarului, adresa IP și numărul portului expeditorului.

Protocoale stratului de transport

Există două protocoale la nivelul de transport: TCP (de încredere) și UDP (nefiabil).

Protocolul UDP

UDP (User Datagram Protocol) efectuează un minim de pași, permițând aplicației să lucreze aproape direct cu stratul de rețea. Funcționează mult mai rapid decât TCP, deoarece nu este nevoie să stabiliți o conexiune și să așteptați confirmarea livrării. Posibila pierdere de segmente. Monitorizează corectitudinea datelor transmise (checksum).

Structura segmentului UDP

Antetul are doar 8 octeți.

Principiile transmisiei fiabile a datelor

Să proiectăm protocolul myTCP, făcându-l treptat mai complex.

  • stările protocolului myTCP 1.0. Transmisie pe un canal complet de încredere
  • Stările protocolului myTCP 1.0 (emițător) (transmisie pe un canal complet de încredere).JPG

    Expeditor

    Stările protocolului myTCP 1.0 (receptor) (transmisie pe un canal complet de încredere).JPG

    Destinatar

  • Stările protocolului myTCP 2.0. Transmisie pe un canal care permite distorsiunea biților. Nu este posibilă pierderea pachetelor
  • Stările protocolului myTCP 2.0 (emițător) (transmisie pe un canal care permite coruperea biților. Nu este posibilă pierderea de pachete).JPG

    Expeditor

    Stările protocolului myTCP 2.0 (receptor) (transmisie pe un canal care permite coruperea biților. Nu este posibilă pierderea de pachete).JPG

    Destinatar

Dar chitanțele se pot pierde și. Dacă chitanța este coruptă, expeditorul trimite din nou pachetul. Destinatarul trebuie să se gândească la modul de procesare a pachetelor repetate (trebuie să introduceți o nouă stare - dacă pachetul anterior a fost transferat în aplicație sau nu).

Rolul identificatorilor „repetați” și „noi” în TCP/IP este jucat de numerele de pachete (deoarece pachetele se pot pierde în continuare).

  • stările protocolului myTCP 2.1. Transmisie pe un canal care permite distorsiunea biților. Nu este posibilă pierderea pachetelor
  • Stările protocolului myTCP 2.1 (emițător) (transmisie pe un canal care permite coruperea biților. Nu este posibilă pierderea de pachete).JPG

    Expeditor

    Stările protocolului myTCP 2.1 (receptor) (transmisie pe un canal care permite coruperea biților. Nu este posibilă pierderea de pachete).JPG

    Destinatar

Principala diferență între statele destinatare este modul în care sunt gestionate pachetele de reluare. În starea „Ultimul pachet a fost trimis în aplicație”, aruncăm pachetele repetate, iar în starea „Ultimul pachet nu a fost transmis în aplicație”, le acceptăm și le transmitem aplicației.

Acum este timpul să ne amintim că pachetele se pot pierde.

  • Trebuie să puteți determina dacă un pachet a fost pierdut, de exemplu, pentru a detecta timpul după ce pachetul este trimis.
  • Pachetele trebuie numerotate.
  • Chitantele trebuie să indice numărul coletului la care a fost trimis.

Astfel, ajungem la necesitatea unui cronometru. În cazul în care vreunul anumit timp iar confirmarea nu este primită, mesajul este retrimis. Intervalul de timp este mic deoarece probabilitatea de pierdere se presupune a fi aproape de 1 (acest lucru este într-adevăr adevărat chiar și pentru o conexiune WiFi bună).

Dezavantajele protocoalelor care așteaptă confirmări

Să ne uităm la un exemplu. Să existe un canal de 1 GB Rostov - Moscova. Să calculăm timpul pentru a trimite 1000 de octeți (sau 8000 de biți):

8000 de biți / 1 Gb/s = 8 µs

Timp de propagare a semnalului:

1000 km / 300.000 km/s = 3333 µs

Total: următorii 1000 de octeți vor fi trimiși în mai mult de 6674 µs

Concluzie: 99,9% din timp canalul nu este folosit.

Soluția este creșterea dimensiunii pachetului. Dar dacă cel puțin 1 bit este distorsionat, atunci întregul pachet va fi aruncat. Atunci ce?

Protocoale ferestre glisante

Soluția problemei: permiteți expeditorului să trimită nu doar un cadru, ci mai multe înainte de a se opri și a intra în modul de așteptare a confirmărilor (chitanțe). Această tehnică se numește prelucrarea transportoarelor.

În figură, verdele indică acele chitanțe care au fost deja primite, galbenul indică cele care au fost trimise dar neprimite, cele albastre sunt pregătite pentru trimitere, iar cele albe nu pot fi trimise până când nu primim chitanțe pentru cele galbene. Fereastra: galben și albastru sunt pachete care pot fi transmise fără a aștepta chitanțe. Primul pachet alb poate fi trimis numai după ce a fost primită confirmarea primului colet galben. Apoi fereastra se deplasează cu 1 la dreapta.

Poate apărea întrebarea: de ce să limităm dimensiunea ferestrei, să transmitem toate pachetele și apoi să așteptăm confirmări. Dar nu poți face asta: este ușor să obții aglomerație în rețea.

Există două modalități de a rezolva problemele de erori la conductele de rame:

  • GBN (Go Back N - returnează N pachete înapoi);
  • SR (Selective Repeat - repetiție selectivă).
GBN

Destinatarul trimite doar chitanțe pozitive și doar despre primirea acelor pachete pentru care este îndeplinită condiția: toate pachetele cu numere mai mici au fost deja primite. Deci aici este folosit strângere de mână de grup: primirea de către expeditor a unei chitanțe cu numărul i înseamnă că toate pachetele până la i inclusiv au fost livrate cu succes. Dacă după ceva timp expeditorul nu primește o chitanță, acesta repetă trimiterea tuturor N pachete începând cu cel de după ultimul confirmat.

Metoda GBN este ineficientă atunci când fereastra este mare și pachetele durează mult pentru a se propaga într-o rețea în care apar pierderi. Exemplu: am trimis 1000 de pachete, al doilea nu a sosit, trebuie să repetăm ​​trimiterea tuturor, începând cu al doilea. Înfundam rețeaua cu trafic inutil.

S.R.

Această abordare presupune trimiterea unei chitanțe pentru fiecare colet. Receptorul stochează în buffer-ul său toate cadrele valide primite după unul nevalid sau pierdut. În acest caz, cadrul incorect este eliminat. Dacă expiră timpul de expirare de primire pentru un cadru, expeditorul trimite din nou acest cadru fără a repeta trimiterea tuturor celor ulterioare. Dacă a doua încercare are succes, pachetele acumulate ale destinatarului pot fi transmise la stratul de rețea, după care va fi trimisă o confirmare de primire a cadrului cu cel mai mare număr.

Adesea, metoda selectivă este combinată cu destinatarul care trimite o „confirmare negativă” (NAK - Negative Acknowledgement) atunci când este detectată o eroare (de exemplu, dacă suma de control este incorectă). În același timp, eficiența muncii crește.

Cu o fereastră mare, abordarea SR poate necesita o dimensiune semnificativă a tamponului.

Protocolul TCP

Format de segment TCP

Un segment TCP constă dintr-un câmp de date și mai multe câmpuri de antet. Câmp de date conține o bucată de date transmise între procese. Dimensiunea câmpului de date este limitată la M.S.S.(dimensiunea maximă a segmentului). Atunci când un protocol transferă un fișier mare, de obicei împarte datele în bucăți de dimensiunea MSS (cu excepția ultimei bucăți, care este de obicei mai mică). În contrast, aplicațiile interactive fac adesea schimb de date care sunt semnificativ mai mici decât MSS. De exemplu, aplicații acces la distanță la o rețea precum Telnet poate transfera 1 octet de date la stratul de transport. Deoarece antetul segmentului TCP are de obicei 20 de octeți (12 octeți mai mare decât UDP), dimensiunea totală a segmentului în acest caz este de 21 de octeți.

Ca în Protocolul UDP, antetul include numerele portului sursă și destinație destinate procedurilor de multiplexare și demultiplexare a datelor, precum și un câmp de sumă de control. În plus, segmentul TCP include și alte câmpuri.

  • Câmpurile pentru numărul de secvență și numărul de confirmare pe 32 de biți. Necesar pentru transferul de date fiabil.
  • Câmpul pentru lungimea antetului de 4 biți specifică lungimea antetului TCP în cuvinte de 32 de biți. Dimensiunea minimă este de 5 cuvinte, iar cea maximă este de 15, adică 20 și, respectiv, 60 de octeți. Antetul TCP poate fi de lungime variabilă datorită câmpului de opțiuni descris mai jos (de obicei, câmpul de opțiuni este gol; aceasta înseamnă că antetul are o lungime de 20 de octeți).
  • Câmpul steagurilor este format din 6 biți. Bitul de confirmare (ACK) indică faptul că valoarea conținută în chitanță este corectă. Biții RST, SYN și FIN sunt utilizați pentru a stabili și a termina o conexiune. Set bit PSH-ul instruiește receptorul să împingă datele acumulate în tamponul de primire către aplicația utilizatorului. Bitul URG indică faptul că segmentul conține date desemnate ca „urgente” de stratul superior. Locația ultimului octet al datelor urgente este indicată în câmpul indicator de date urgente de 16 biți. La capătul de recepție, TCP trebuie să notifice stratul superior că există date urgente în segment și să îi transmită un pointer către sfârșitul acelor date. În practică, steaguri PSH, URG și câmpul indicator de date urgente nu sunt utilizate. Le-am menționat doar pentru caracterul complet al descrierii.
  • O fereastră de primire pe 16 biți este utilizată pentru controlul fluxului de date. Conține numărul de octeți pe care partea de recepție este capabilă să-i primească.
  • Indicatorul de importanță este o valoare de offset pozitivă de 16 biți față de numărul de secvență dintr-un segment dat. Acest câmp indică numărul de secvență al octetului care încheie datele urgente. Câmpul este luat în considerare doar pentru pachetele cu steagul URG setat.
  • Un câmp de parametri opțional este utilizat în cazurile în care părțile care trimite și cele care primesc sunt „de acord” cu privire la dimensiunea maximă a segmentului sau pentru a scala fereastra în rețelele de mare viteză. Acest câmp definește, de asemenea, parametrul timestamp. Informații suplimentare poate fi găsit în RFC 854 și RFC 1323.
Numere de ordine și de confirmare

Numărul secvenței segmentului este numărul primului octet al acestui segment.

Număr de confirmare este numărul de secvență al următorului octet așteptat.

Câmpurile numărul de secvență și numărul de confirmare sunt cele mai importante câmpuri din antetul segmentului TCP deoarece joacă un rol cheie în funcționarea serviciului de transfer de date fiabil. Cu toate acestea, înainte de a lua în considerare rolul acestor câmpuri în mecanismul de transmisie fiabil, să ne uităm la valorile pe care TCP le plasează în aceste câmpuri.

Protocolul TCP tratează datele ca pe un flux nestructurat, ordonat de octeți. Această abordare se manifestă prin faptul că TCP atribuie numere de secvență nu segmentelor, ci fiecărui octet transmis. Pe baza acestui fapt, numărul de secvență al unui segment este definit ca numărul de secvență al primului octet al acestui segment. Luați în considerare următorul exemplu. Lăsați gazda A să dorească să redirecționeze un flux de date către gazda B printr-o conexiune TCP. Protocolul TCP de pe partea de trimitere numește implicit fiecare octet al fluxului. Lasă dimensiunea fișier transferat este de 500.000 de octeți, valoarea MSS este de 1000 de octeți, iar primul octet al fluxului are numărul de secvență 0. TCP împarte fluxul de date în 500 de segmente. Primului segment i se atribuie numărul de secvență 0, celui de-al doilea segment i se atribuie numărul 1000, celui de-al treilea segment i se atribuie numărul 2000 etc. Numerele de secvență sunt introduse în câmpurile cu numărul de secvență ale fiecărui segment TCP.

Acum să ne uităm la numerele de confirmare. Reamintim că protocolul TCP asigură transmisie de date duplex, adică printr-o singură conexiune TCP, datele între gazdele A și B pot fi transmise simultan în ambele direcții. Fiecare segment care provine de la gazda B conține numărul de secvență al datelor transmise de la gazda B la gazda A. Numărul de confirmare pe care gazda A îl plasează în segmentul său este numărul de secvență al următorului octet pe care gazda A îl așteaptă de la gazda B. Luați în considerare exemplul următor. Să presupunem că gazda A a primit toți octeții numerotați de la 0 la 535 trimiși de gazda B și formează un segment pe care să-l trimită către gazda B. Gazda A se așteaptă ca următorii octeți trimiși de gazda B să fie numerotați începând cu 536 și plasează numărul 536 în confirmare câmpul numeric al segmentului dvs.

Să luăm în considerare o altă situație. Lăsați gazda A să primească două segmente de la gazda B, primul dintre care conține octeți numerotați de la 0 la 535, iar al doilea conține octeți numerotați de la 900 la 1000. Aceasta înseamnă că din anumite motive octeții numerotați de la 536 la 899 nu au fost primiți de gazda A. În în acest caz, gazda A așteaptă octeții lipsă și plasează numărul 536 în câmpul său de număr de confirmare a segmentului Deoarece strângerea de mână TCP a primit date până la primul octet lipsă, se spune că acceptă o strângere de mână generală.

Acest ultim exemplu demonstrează un aspect foarte important al modului în care funcționează TCP. Al treilea segment (conținând octeții 900-1000) a fost primit de gazda A mai devreme decât al doilea (conținând octeții 536-899), adică încălcând ordinea datelor. Apare întrebarea: cum răspunde TCP la perturbarea ordinii? Dacă segmentul primit conține un număr de secvență mai mare decât cel așteptat, atunci datele din segment sunt stocate în tampon, dar numărul de secvență confirmat nu este modificat. Dacă un segment corespunzător numărului de secvență așteptat este primit ulterior, ordinea datelor va fi restabilită automat pe baza numerelor de secvență din segmente. Astfel, TCP este un protocol SR, dar folosește o strângere de mână obișnuită precum GBN. Deși SR nu este în întregime pură. Dacă partea care trimite primește mai multe (3) chitanțe negative pentru același segment x, atunci ghicește că a avut loc congestionarea rețelei și segmentele x+1, x+2, x+3,... nu au fost, de asemenea, livrate. Apoi întreaga serie este trimisă începând de la x - ca în protocoalele GBN.

Probleme cu dimensiunea maximă a segmentului

TCP necesită o dimensiune maximă explicită a segmentului dacă conexiunea virtuală este peste un segment de rețea în care dimensiunea maximă a unității (MTU) este mai mică decât MTU Ethernet standard (1500 de octeți). În protocoalele de tunel, cum ar fi GRE, IPIP, precum și PPPoE, tunelul MTU este mai mic decât cel standard, astfel încât dimensiunea maximă a segmentului TCP are o lungime a pachetului mai mare decât MTU. Deoarece fragmentarea este interzisă în marea majoritate a cazurilor, astfel de pachete sunt aruncate.

Manifestarea acestei probleme arată ca conexiuni „atârnate”. În acest caz, „înghețarea” poate apărea în momente arbitrare, și anume atunci când expeditorul a folosit segmente mai lungi decât dimensiunea admisă. Pentru a rezolva această problemă, routerele folosesc reguli de firewall care adaugă un parametru MSS la toate pachetele care inițiază conexiuni, astfel încât expeditorul să folosească segmente de dimensiune validă. MSS poate fi controlat și prin parametrii sistemului de operare.

Triplă strângere de mână

Pentru a stabili o conexiune, gazda 2 așteaptă pasiv o conexiune de intrare executând primitiva ACCEPT.

Gazda 2 execută primitiva CONNECT, indicând adresa IP și portul cu care dorește să se conecteze, dimensiunea maximă a segmentului TCP, etc. Primitiva CONNECT trimite un segment TCP „Connection request” cu SYN=1 bit setat și bitul șters. ACK=0 și așteaptă un răspuns. Deci gazda 1 raportează numărul de secvență x al secvenței de biți de la gazda 1 la 2.

Gazda 2 trimite înapoi o confirmare „Conexiune acceptată” (funcția de acceptare). Secvența segmentelor TCP trimise în cazul normal este prezentată în Fig: SYN=1 ASK=1, gazda 2 raportează numărul de secvență x al secvenței de biți de la gazda 2 la 1 și raportează că se așteaptă ca datele să continue începând de la octetul nr. . x+1.

Gazda 1 (Conectare) trimite confirmarea că a primit consimțământul pentru stabilirea conexiunii.

Controlul congestiei TCP

Când orice rețea primește mai multe date decât poate gestiona, rețeaua devine aglomerată. Internetul în acest sens nu face excepție. Deși stratul de rețea încearcă să facă față și congestiei, principala contribuție la rezolvarea acestei probleme, care este reducerea ratei de transfer de date, o are protocolul TCP.

Teoretic, congestia poate fi tratată folosind un principiu împrumutat din fizică - legea conservării pachetelor. Ideea este de a nu transmite noi pachete în rețea până când cele vechi nu au plecat (adică au fost livrate). Protocolul TCP încearcă să atingă acest obiectiv controlând dinamic dimensiunea ferestrei.

Primul pas în a face față supraîncărcării este să o recunoașteți. Cu câteva decenii în urmă, detectarea congestionării rețelei era dificilă. Era greu de înțeles de ce coletul nu a fost livrat la timp. Pe lângă posibilitatea de congestie a rețelei, a existat și o probabilitate mare de pierdere a pachetelor din cauza nivel înalt interferență pe linie.

În prezent, pierderea pachetelor în timpul transmisiei este relativ rară, deoarece majoritatea liniilor de comunicații la distanță lungă sunt pe fibră optică (deși în rețele fără fir procentul de pachete pierdute din cauza interferenţelor este destul de mare). În consecință, majoritatea pachetelor pierdute de pe Internet sunt cauzate de congestie. Toți algoritmii Internet TCP presupun că pierderile de pachete sunt cauzate de congestionarea rețelei și urmăresc timpul de expirare ca un semn de avertizare al problemelor.

Înainte de a discuta modul în care TCP răspunde la congestie, descriem mai întâi tehnicile de evitare a congestionării protocolului. Când este detectată o suprasarcină, trebuie selectată o dimensiune adecvată a ferestrei. Destinatarul poate specifica dimensiunea ferestrei în funcție de cantitate spatiu liberîn tampon. Dacă expeditorul ține cont de dimensiunea ferestrei sale, o depășire a memoriei tampon la receptor poate să nu cauzeze problema, dar poate apărea din cauza congestionării undeva în rețea între expeditor și receptor.

Controlul congestiei TCP

Să ilustrăm această problemă folosind exemplul unui sistem de alimentare cu apă. În figura a vedem o țeavă groasă care duce la un recipient cu un mic recipient. Atâta timp cât expeditorul nu trimite mai multă apă decât poate încăpea în găleată, apa nu se va vărsa în Figura b, factorul limitativ nu este capacitatea găleții, dar debitului retelelor. Dacă apa curge prea repede de la robinet în pâlnie, nivelul apei din pâlnie va începe să crească și, în cele din urmă, o parte din apă poate revărsa marginea pâlniei.

Soluția Internet este să recunoaștem că există două probleme potențiale: debit redus al rețelei și capacitate scăzută a receptorului și să rezolvi ambele probleme separat. Pentru a face acest lucru, fiecare expeditor are două ferestre: fereastra furnizată de receptor și fereastra de supraîncărcare. Mărimea fiecăruia dintre ele corespunde numărului de octeți pe care expeditorul are voie să îi transmită. Expeditorul folosește minimul acestor două valori. De exemplu, receptorul spune „Trimite 8 KB”, dar expeditorul știe că dacă trimite mai mult de 4 KB, va fi o congestie în rețea, așa că trimite oricum 4 KB. Dacă expeditorul știe că rețeaua este capabilă să transmită o cantitate mai mare de date, de exemplu 32 KB, va transmite atât cât solicită destinatarul (adică 8 KB).

Când se stabilește o conexiune, expeditorul setează dimensiunea ferestrei de congestie la dimensiunea segmentului maxim utilizat pe conexiune. Apoi transmite un segment maxim. Dacă o confirmare a acestui segment sosește înainte de expirarea perioadei de expirare, dimensiunea segmentului este adăugată la dimensiunea ferestrei, adică dimensiunea ferestrei de congestionare este dublată și sunt trimise două segmente. Ca răspuns la confirmarea primirii fiecăruia dintre segmente, fereastra de congestie este extinsă cu valoarea unui segment maxim. Să presupunem că dimensiunea ferestrei este de n segmente. Dacă confirmările pentru toate segmentele sosesc la timp, fereastra este mărită cu numărul de octeți corespunzători n segmente. În esență, recunoașterea fiecărei secvențe de segmente duce la dublarea ferestrei de congestie.

Acest proces de creștere exponențială continuă până când este atinsă dimensiunea ferestrei receptorului sau este generat un indicator de timeout, semnalând congestia rețelei. De exemplu, dacă pachetele de dimensiunea 1024, 2048 și 4096 de octeți ajung la destinatar cu succes, dar ca răspuns la transmiterea unui pachet de dimensiunea de 8192 de octeți, confirmarea nu ajunge în limita de timp specificată, fereastra de congestie este setată la 4096 de octeți. . Atâta timp cât dimensiunea ferestrei de congestie rămâne la 4096 de octeți, pachetele nu mai sunt trimise, indiferent de dimensiunea ferestrei furnizate de destinatar. Acest algoritm este numit început lung, sau pornire lent. Cu toate acestea, nu este atât de lent (Jacobson, 1988). Este exponenţial. Toate implementările protocolului TCP sunt necesare pentru a-l sprijini.

Să luăm acum în considerare mecanismul de control al congestiei utilizat pe Internet. Pe lângă ferestrele receptorului și congestie, folosește o valoare de prag ca al treilea parametru, care este setat inițial la 64 KB. Când apare o condiție de expirare (confirmarea nu este returnată la timp), noua valoare de prag este setată la jumătate din dimensiunea actuală a ferestrei de congestie, iar fereastra de congestie este redusă la dimensiunea unui segment maxim. Apoi, ca și în cazul precedent, se folosește un algoritm de pornire lentă pentru a detecta rapid limita capacității rețelei. Cu toate acestea, de această dată creșterea exponențială a dimensiunii ferestrei se oprește atunci când atinge un prag, după care fereastra crește liniar, cu câte un segment pentru fiecare transmisie ulterioară. În esență, presupunerea este că puteți înjumătăți în siguranță dimensiunea ferestrei de congestie și apoi o puteți crește treptat.

Mecanisme de transmisie fiabile. Generalizare

Sumă de control Detectarea corupției biților într-un pachet primit
Cronometru Numărează invers intervalul de timeout și indică când a expirat. Aceasta din urmă înseamnă că, cu un grad mare de probabilitate, pachetul sau primirea acestuia se pierde în timpul transmisiei. Dacă un pachet este livrat cu întârziere, dar nu este pierdut (expirarea prematură a intervalului de expirare) sau se pierde o chitanță, retransmiterea duce la duplicarea pachetului pe partea de primire.
Numere de serie Numerotarea secvenţială a pachetelor trimise de partea care transmite. „Lacunele” în numărul de pachete primite ne permit să concluzionam că datele s-au pierdut. Aceleași numere de secvență de pachete înseamnă că pachetele sunt duplicate unul față de celălalt
Chitanțe „+” și „-”. Generat de capătul de recepție și indicând capătului de expediere că pachetul sau grupul de pachete corespunzător a fost sau nu a fost primit. De obicei, confirmarea conține numerele de secvență ale pachetelor primite cu succes. În funcție de protocol, se disting confirmările individuale și de grup
Fereastra/conveior Limitați gama de numere de secvență care pot fi utilizate pentru a transmite pachete. Transmisia multicast și handshaking pot crește semnificativ debitul protocolului în comparație cu așteptarea confirmărilor. Dimensiunea ferestrei poate fi calculată pe baza capacităților de recepție și tamponare ale capătului de recepție, precum și a nivelului de încărcare a rețelei

Caracteristici de programare

  1. Conexiune de streaming TCP
    • situaţia a) este posibilă când conexiune proasta, dacă intervalul de timp dintre sosiri de grupuri de datagrame de nivel de rețea este mare:
      • computer1 folosește funcția de trimitere o dată;
      • computer2 nu primește toate informațiile într-un apel recv (sunt necesare mai multe apeluri).
    • situația b) este posibilă dacă intervalul de timp dintre apelurile la funcția de trimitere este mic și dimensiunea datelor este mică:
      • computer1 folosește funcția de trimitere de mai multe ori;
      • computer2 primește toate informațiile într-un apel recv.
  2. Prin protocolul UDP
    • situația a) - imposibilă
      • computer1 folosește funcția de trimitere o dată la nivel de rețea, segmentul UDP este împărțit în mai multe pachete;
      • computer2 primește întotdeauna segmentul cu un apel recv și numai dacă au sosit toate datagramele IP.
    • situatia b) - imposibila
      • diferite apeluri la funcția sendto de pe computer1 corespund diferitelor datagrame UDP și provocări diferite recvde pe computer2.
  3. Dacă buffer-ul din funcțiile recv și recvfrom este mai mic decât dimensiunea datelor trimise, atunci în cazul UDP, o parte din date se pierde, iar în cazul TCP, restul este salvat pentru apelul recv ulterior.
  4. Un server UDP are 1 socket, iar un server TCP are multe socket-uri diferite (în funcție de numărul de clienți conectați simultan) și fiecare primește informații proprii.

Accelerarea oricăror procese este imposibilă fără o reprezentare detaliată a structurii lor interne. Accelerarea internetului este imposibilă fără înțelegerea (și configurarea adecvată) a protocoalelor fundamentale - IP și TCP. Să înțelegem caracteristicile protocoalelor care afectează viteza Internetului.

IP (Internet Protocol) oferă rutare și adresare de la gazdă la gazdă. TCP (Transmission Control Protocol) oferă o abstractizare în care o rețea funcționează în mod fiabil pe un canal inerent nefiabil.

Protocoalele TCP/IP au fost propuse de Vint Cerf și Bob Kahn în lucrarea „A Communications Protocol for a Packet-Based Network”, publicată în 1974. Propunerea originală, înregistrată ca RFC 675, a fost editată de mai multe ori, iar în 1981, versiunea 4 a specificației TCP/IP a fost publicată ca două RFC-uri diferite:

  • RFC 791 – Protocol Internet
  • RFC 793 – Protocolul de control al transmisiei

De atunci, TCP au fost aduse mai multe îmbunătățiri, dar fundația lui rămâne aceeași. TCP a înlocuit rapid alte protocoale și acum alimentează componentele de bază ale modului în care gândim internetul: site-uri web, e-mail, transfer de fișiere și altele.

TCP oferă abstracția necesară conexiuni de rețea, astfel încât aplicațiile să nu aibă de a face cu diverse sarcini conexe, cum ar fi: retransmiterea datelor pierdute, livrarea datelor către într-o anumită ordine, integritatea datelor și altele asemenea. Când lucrați cu un flux TCP, știți că octeții trimiși vor fi identici cu cei primiți și că vor ajunge în aceeași ordine. Putem spune că TCP se concentrează mai mult pe corectitudinea livrării datelor, și nu pe viteză. Acest fapt creează o serie de probleme atunci când vine vorba de optimizarea performanței site-ului.

Standardul HTTP nu necesită utilizarea TCP ca protocol de transport. Dacă vrem, putem transmite HTTP printr-un socket de datagramă (UDP - User Datagram Protocol) sau prin orice altul. Dar, în practică, tot traficul HTTP este transmis prin TCP, datorită confortului acestuia din urmă.

Prin urmare, este necesar să înțelegem unele dintre mecanismele interne ale TCP pentru a optimiza site-urile. Probabil că nu veți lucra cu socket-uri TCP direct în aplicația dvs., dar unele dintre deciziile dvs. de proiectare a aplicației vor dicta performanța TCP-ului pe care va rula aplicația dvs.

Strângere de mână în trei căi

Toate conexiunile TCP încep cu o strângere de mână în trei căi (Figura 1). Înainte ca clientul și serverul să poată schimba orice date aplicației, ei trebuie să „să fie de acord” cu privire la semințele secvenței de pachete, precum și o serie de alte variabile asociate cu acea conexiune. Numerele de secvență sunt alese aleatoriu pe ambele părți pentru securitate.

SYN

Clientul selectează un număr aleator X și trimite un pachet SYN, care poate conține, de asemenea, indicatori TCP și valori opțiuni suplimentare.

SYN ACK

Serverul își selectează propriul număr aleator Y, adaugă 1 la valoarea lui X, adaugă steaguri și opțiuni și trimite un răspuns.

ÎNTREBĂ

Clientul adaugă 1 la valorile lui X și Y și completează strângerea de mână prin trimiterea unui pachet ACK.



Orez. 1. Strângere de mână în trei căi.

Odată ce strângerea de mână este încheiată, schimbul de date poate începe. Clientul poate trimite un pachet de date imediat după pachetul ACK, serverul trebuie să aștepte ca pachetul ACK să înceapă să trimită date. Acest proces are loc pe fiecare conexiune TCP și reprezintă o provocare serioasă în ceea ce privește performanța site-ului. La urma urmei, fiecare nouă conexiune înseamnă o întârziere de rețea.

De exemplu, dacă clientul este în New York, serverul este în Londra și creăm o nouă conexiune TCP, va dura 56 de milisecunde. 28 de milisecunde pentru ca un pachet să călătorească într-o direcție și aceeași cantitate pentru a se întoarce la New York. Lățimea canalului nu joacă niciun rol aici. Crearea conexiunilor TCP poate fi costisitoare, astfel încât reutilizarea conexiunii este o caracteristică importantă de optimizare pentru orice aplicație bazată pe TCP.

Deschidere rapidă TCP (TFO)

Încărcarea unei pagini poate însemna descărcarea a sute de părți de la diferite gazde. Acest lucru poate necesita browser-ului să creeze zeci de noi conexiuni TCP, fiecare dintre ele va suferi latență din cauza strângerii de mână. Inutil să spun că acest lucru poate înrăutăți viteza de încărcare a unei astfel de pagini, în special pentru utilizatorii de telefonie mobilă.

TCP Fast Open (TFO) este un mecanism care reduce latența permițând trimiterea datelor într-un pachet SYN. Cu toate acestea, are și limitările sale: în special, cu privire la dimensiunea maximă a datelor din interiorul unui pachet SYN. În plus, numai anumite tipuri de solicitări HTTP pot folosi TFO și funcționează doar pentru conexiunile de reluare deoarece utilizează un cookie.

Utilizarea TFO necesită suport explicit pentru acest mecanism pe client, server și aplicație. Acest lucru funcționează pe un server cu nucleu versiuni Linux 3.7 și versiuni ulterioare și cu un client compatibil (Linux, iOS9 și versiuni ulterioare, OSX 10.11 și versiuni ulterioare) și va trebui, de asemenea, să activați steaguri de socket corespunzătoare în cadrul aplicației.

Experții Google au stabilit că TFO poate reduce latența rețelei pentru solicitările HTTP cu 15%, poate accelera încărcarea paginii cu 10% în medie și, în unele cazuri, cu până la 40%.

Controlul suprasarcinii

La începutul anului 1984, John Nagle a descris o condiție de rețea pe care a numit-o „colapsul congestiei”, care se poate forma în orice rețea în care lățimile canalelor dintre noduri sunt inegale.

Când întârzierea dus-întors (durata dus-întors pentru pachete) depășește intervalul maxim de retransmisie, gazdele încep să trimită în rețea copii ale acelorași datagrame. Acest lucru va face ca bufferele să devină pline și pachetele să se piardă. Ca urmare, gazdele vor trimite pachete de mai multe ori, iar după mai multe încercări pachetele vor ajunge la țintă. Acest lucru se numește „colapsul congestiei”.

Nagle a arătat că colapsul congestiei nu era o problemă pentru ARPANETN la acea vreme, deoarece nodurile aveau lățimi de canal egale, iar coloana vertebrală avea o capacitate în exces. Cu toate acestea, acest lucru nu mai este cazul pe internetul modern. În 1986, când numărul de noduri din rețea a depășit 5000, au avut loc o serie de colapsuri de congestie. În unele cazuri, acest lucru a făcut ca viteza rețelei să scadă cu un factor de 1000, ceea ce înseamnă că era efectiv inutilizabilă.

Pentru a face față acestei probleme, TCP a implementat mai multe mecanisme: controlul fluxului, controlul congestiei și evitarea congestiei. Ei au determinat viteza cu care datele pot fi transferate în ambele direcții.

Controlul fluxului

Controlul fluxului previne trimiterea prea mult cantitate mare date destinatarului pe care acesta nu le poate prelucra. Pentru a preveni acest lucru, fiecare parte a conexiunii TCP raportează cantitatea de spațiu tampon disponibil pentru datele de intrare. Acest parametru este „fereastră de primire” (rwnd).

Când se stabilește o conexiune, ambele părți își stabilesc valorile rwn pe baza setărilor implicite ale sistemului. Deschiderea unei pagini web tipice va însemna trimiterea multor date de la server către client, astfel încât fereastra de recepție a clientului va fi limitatorul principal. Cu toate acestea, dacă clientul trimite multe date către server, de exemplu prin încărcarea unui videoclip acolo, atunci fereastra de primire a serverului va fi factorul limitativ.

Dacă dintr-un motiv oarecare o parte nu poate face față fluxului de date de intrare, trebuie să raporteze o valoare redusă pentru fereastra de recepție. Dacă fereastra de primire ajunge la 0, aceasta semnalează expeditorului să nu mai trimită date până când buffer-ul receptorului este golit la nivelul aplicației. Această secvență se repetă continuu pe fiecare conexiune TCP: fiecare pachet ACK poartă o valoare nouă rwnd pentru ambele părți, permițându-le să ajusteze dinamic rata de date în funcție de capacitățile destinatarului și ale expeditorului.



Orez. 2. Transmiterea valorii ferestrei de primire.

Scalarea ferestrei (RFC 1323)

Specificația originală TCP a limitat dimensiunea valorii ferestrei de recepție transmise la 16 biți. Acest lucru l-a limitat sever în partea de sus, deoarece fereastra de recepție nu putea fi mai mare de 216 sau 65.535 de octeți. S-a dovedit că acest lucru nu este adesea suficient pentru o performanță optimă, în special în rețelele cu un „produs cu întârziere a lățimii de bandă” (BDP) mare.

Pentru a combate această problemă, RFC 1323 a introdus opțiunea de scalare a ferestrei TCP, care a permis mărirea dimensiunii ferestrei de recepție de la 65.535 de octeți la 1 gigaoctet. Parametrul de scalare a ferestrei este trimis în strângere de mână cu trei căi și reprezintă numărul de biți care trebuie deplasat la stânga pe dimensiunea ferestrei de primire de 16 biți în următoarele pachete ACK.

Astăzi, scalarea ferestrei de recepție este activată în mod implicit pe toate platformele majore. Cu toate acestea, noduri intermediare, routere și firewall-uri poate suprascrie sau chiar elimina această setare. Dacă conexiunea dvs. nu poate utiliza pe deplin întregul canal, trebuie să începeți prin a verifica valorile ferestrelor de recepție. Pe platforma Linux, opțiunea de scalare a ferestrei poate fi verificată și setată astfel:

$> sysctl net.ipv4.tcp_window_scaling $> sysctl -w net.ipv4.tcp_window_scaling=1

În următoarea parte, vom afla ce este TCP Slow Start, cum să optimizăm rata de transfer de date și să creștem fereastra inițială și, de asemenea, vom reuni toate recomandările pentru optimizarea stivei TCP/IP.

TCP Triple Handshake

Procesul de pornire a unei sesiuni TCP (numit și strângere de mână) constă din trei pași.

1. Un client care intenționează să stabilească o conexiune trimite un segment cu un număr de secvență și un steag SYN către server.

  • Serverul primește segmentul, își amintește numărul de secvență și încearcă să creeze un socket (buffere și structuri de memorie de control) pentru a servi noul client.
    • Dacă are succes, serverul trimite clientului un segment cu un număr de secvență și steagurile SYN și ACK și intră în starea SYN-RECEIVED.
    • În caz de eșec, serverul trimite clientului un segment cu steag RST.

2. Dacă clientul primește un segment cu flag SYN, atunci își amintește numărul de secvență și trimite segmentul cu flag ACK.

  • Dacă primește și flagul ACK în același timp (ceea ce se întâmplă de obicei), atunci intră în starea ESTABLISHED.
  • Dacă clientul primește un segment cu steag RST, nu mai încearcă să se conecteze.
  • Dacă clientul nu primește un răspuns în 10 secunde, acesta repetă din nou procesul de conectare.

3. Dacă serverul în starea SYN-RECEIVED primește un segment cu steag ACK, atunci acesta intră în starea ESTABLISHED.

  • În caz contrar, după un timeout, închide soclul și intră în starea ÎNCHIS.

Procesul se numește „negociare în trei sensuri” deoarece, deși este posibilă stabilirea unei conexiuni folosind patru segmente (SYN către server, ACK către client, SYN către client, ACK către server), în practică trei sunt folosite pentru a economisiți timp.

TCP - fereastra

Acest câmp conține un număr care specifică, în octeți, dimensiunea datelor pe care expeditorul le poate trimite fără a primi o confirmare.

fereastra TCP – un algoritm pentru controlul intensității fluxului de date, bazat pe modificarea cantității maxime de date pe care destinatarul este gata să le accepte și să le confirme cu un singur segment de răspuns
Dimensiunea ferestrei este întotdeauna atribuită de către destinatar, pe baza statisticilor privind numărul de erori

Domenii de coliziune

Domeniul de coliziune- Asta zona de reteaEthernet, toate nodurile care recunosc o coliziune, indiferent în ce parte a acestei zone are loc ciocnirea

  • Conflictul rezultat nu se extinde dincolodomeniul de coliziune corespunzător
  • Cu cât este mai mare numărul de domenii de coliziune, cu atât consecințele fiecărei coliziuni sunt mai puțin vizibile
  • Pentru a împărți rețeaua acasăFolosim comutatoare de coliziune

Moduri de operare VTP pe comutatoare

VTP - VLAN Trunking Protocol, vă permite să simplificați administrarea switch-urilor, și anume gestionarea VLAN-urilor pe switch-urile Cisco. Cu VTP, puteți crea, modifica sau șterge VLAN-uri pe serverul VTP, iar toate aceste modificări vor fi transferate automat către toate switch-urile din același domeniu VTP. Acest lucru îl scutește pe administrator de configurarea VLAN-urilor pe fiecare comutator.
Există trei moduri de operare VTP:

1. Server VTP - modul server În acest mod, puteți crea, șterge și modifica VLAN-uri, precum și setați diverși parametri, cum ar fi versiunea de protocol (versiunea vtp), filtrarea vtp (tunderea vtp) pentru întregul domeniu VTP. Serverul VTP notifică alte switch-uri situate în același domeniu VTP despre configurația sa VLAN și sincronizează configurația lor VLAN. De asemenea, serverul VTP își poate sincroniza configurația cu configurația VTP a clientului dacă clientul are un număr de revizuire a configurației mai mare. Schimbul de informații VTP are loc prin porturile TRUNK.

2. Client VTP - modul client. La un comutator cu modul VTP Client, nu puteți crea, șterge sau modifica VLAN-uri. Comutatorul preia toate setările VLAN de la serverul VTP.

3. VTP Transparent - mod transparent. În acest mod, comutatorul nu își aplică configurația VLAN de la serverul VTP și nu notifică alte switch-uri despre configurația sa, dar permite notificărilor de la alte switch-uri să treacă prin porturile sale trunk VTP.

Strângere de mână

În cadrul conexiunii, transmiterea corectă a fiecărui segment trebuie confirmată printr-o chitanță de la destinatar. Strângere de mână este una dintre metodele tradiționale de asigurare a unei comunicări fiabile. Ideea din spatele strângerii de mână este următoarea.

Pentru a organiza retransmiterea datelor corupte, expeditorul numerotează unitățile transmise de date transmise (denumite în continuare cadre pentru simplitate). Pentru fiecare cadru, expeditorul așteaptă de la receptor o așa-numită primire pozitivă - un mesaj de serviciu care anunță că cadrul original a fost primit și că datele din acesta au fost corecte. Acest timp de așteptare este limitat - la trimiterea fiecărui cadru, emițătorul pornește un temporizator, iar dacă după expirarea acestuia nu este primită o chitanță pozitivă, atunci cadrul este considerat pierdut. În unele protocoale, receptorul, dacă primește un cadru cu date corupte, trebuie să trimită o confirmare negativă - o indicație clară că cadrul trebuie retransmis.