Uzgadnianie 3-kierunkowe TCP działa w następujący sposób:
Client ------SYN-----> Server
Client <---ACK/SYN---- Server
Client ------ACK-----> Server
Dlaczego nie tylko to?
Client ------SYN-----> Server
Client <-----ACK------ Server
tcp
protocol-theory
layer4
transport-protocol
smwikipedia
źródło
źródło
Odpowiedzi:
Rozbij uścisk dłoni na to, co naprawdę robi.
W TCP obie strony śledzą wysyłane wiadomości, używając numeru sekwencji. W efekcie jest to liczba bajtów bieżących wszystkiego, co zostało wysłane. Strona odbierająca może użyć numeru sekwencyjnego przeciwnego mówcy, aby potwierdzić otrzymaną wiadomość.
Ale numer kolejny nie zaczyna się od 0. Zaczyna się od ISN (Initial Sequence Number), czyli losowo wybranej wartości. A ponieważ TCP jest dwukierunkową komunikacją, obie strony mogą „mówić”, a zatem obie muszą losowo wygenerować numer ISN jako początkowy numer sekwencji. Co z kolei oznacza, że obie strony muszą powiadomić drugą stronę o początkowym numerze ISN.
Tak więc kończy się następująca sekwencja zdarzeń na początek rozmowy TCP między Alicją i Bobem:
Uwaga, występują cztery zdarzenia:
W rzeczywistości dwa środkowe zdarzenia (# 2 i # 3) mają miejsce w tym samym pakiecie. To, co sprawia, że pakiet jest
SYN
lubACK
jest po prostu flagą binarną włączaną lub wyłączaną wewnątrz każdego nagłówka TCP , więc nic nie stoi na przeszkodzie, aby obie te flagi były włączone w tym samym pakiecie. Tak więc potrójny uścisk dłoni jest następujący:Zwróć uwagę na dwa wystąpienia „SYN” i „ACK”, po jednym w obu, w obu kierunkach.
Wracając do pytania, dlaczego nie skorzystać z dwukierunkowego uścisku dłoni? Krótka odpowiedź jest taka, że dwukierunkowy uścisk dłoni pozwoliłby tylko jednej stronie na ustanowienie numeru ISN, a drugiej stronie na jego potwierdzenie. Co oznacza, że tylko jedna strona może wysyłać dane.
Ale TCP jest dwukierunkowym protokołem komunikacyjnym, co oznacza, że każdy z nich powinien być w stanie niezawodnie wysyłać dane. Obie strony muszą ustanowić numer ISN, a obie strony muszą potwierdzić numer ISN drugiej strony.
W efekcie masz dokładnie opis dwukierunkowego uścisku dłoni, ale w każdym kierunku . Stąd cztery zdarzenia. I znowu środkowe dwie flagi występują w tym samym pakiecie. W związku z tym trzy pakiety są zaangażowane w pełny proces inicjowania połączenia TCP.
źródło
The three-way handshake jest konieczne, ponieważ obie strony muszą TRANSMISSION chronize ich numery sekwencyjne segmentów stosowanych podczas ich przesyłania. W tym celu, każdy z nich wysyła (kolejno) segmentu SYN z numerem sekwencję losowej wartości n , który następnie ACK nowledged przez drugą stronę za pomocą segmentu ACK z numerem sekwencji ustawiony n + 1 .
źródło
Eddie
komentarza do swojej odpowiedzi.Aby połączenie działało, każda strona musi sprawdzić, czy może wysyłać pakiety na drugą stronę. Jedynym sposobem, aby upewnić się, że dostałeś pakiet na drugą stronę, jest uzyskanie od nich pakietu, który z definicji nie zostałby wysłany, gdyby pakiet, który wysłałeś, nie przeszedł . TCP zasadniczo używa do tego dwóch rodzajów komunikatów: SYN (aby zażądać dowodu, że ten pakiet przeszedł) i ACK (który jest wysyłany dopiero po przejściu SYN, aby udowodnić, że SYN przeszedł). Jest właściwie trzeci rodzaj wiadomości, ale do tego przejdziemy za chwilę.
Przed rozpoczęciem połączenia żadna ze stron tak naprawdę nic nie wie o drugiej stronie. Klient wysyła pakiet SYN do serwera, aby zażądać dowodu, że jego wiadomości mogą się przedostać . To nic nie mówi żadnej osobie, ale jest to pierwszy krok uścisku dłoni.
Jeśli SYN przejdzie, serwer wie, że klient może wysyłać do niego pakiety, ponieważ, no cóż, tak się właśnie stało. Ale to nie dowodzi, że serwer może odsyłać pakiety z powrotem: klienci mogą wysyłać SYN z wielu powodów . Tak więc serwer musi wysłać dwa komunikaty z powrotem do klienta: ACK (aby udowodnić, że SYN przeszedł) i SYN (aby poprosić o własne ACK). TCP łączy te dwa komunikaty w jeden komunikat SYN-ACK, jeśli chcesz - w celu zmniejszenia ruchu w sieci. To drugi krok uścisku dłoni.
Ponieważ SYN-ACK jest ACK, klient wie teraz na pewno, że może wysyłać pakiety do serwera. A ponieważ SYN-ACK jest SYN, wie również, że serwer chce udowodnić, że ten komunikat został przesłany. Odsyła więc ACK: tym razem zwykłe ACK, ponieważ nie potrzebuje już dowodu, że jego pakiety mogą się przedostać. To jest ostatni krok uzgadniania: klient wie teraz, że pakiety mogą iść w obie strony, i że serwer zaraz się zorientuje (ponieważ wie, że ACK przejdzie).
Po przejściu tego ACK serwer wie, że może wysyłać pakiety do klienta . Wie również, że klient wie o tym, więc może natychmiast rozpocząć wysyłanie danych. Uścisk dłoni został zakończony. Mamy dobry kanał.
Ściśle mówiąc, nie możemy być pewni, że mamy dobry kanał . Tylko dlatego, że ta sekwencja pakietów dotarła nie bezwzględnie zagwarantować, że inni będą. Nie możemy tego udowodnić bez wysłania nieskończonej liczby SYN-ów i ACK-ów, a wtedy nic innego się nigdy nie da zrobić, więc to nie jest tak naprawdę praktyczna opcja. Ale w praktyce trzy kroki okazują się wystarczające do większości celów .
źródło
W rzeczywistości trójdrożny uścisk dłoni nie jest jedynym sposobem na nawiązanie połączenia TCP. Dozwolona jest również jednoczesna wymiana SYN: http://www.tcpipguide.com/free/t_TCPConnectionEstablishmentProcessTheThreeWayHandsh-4.htm
Można to uznać za rodzaj podwójnego dwukierunkowego uścisku dłoni.
źródło
Połączenie TCP jest dwukierunkowe. Oznacza to, że tak naprawdę jest to para połączeń jednokierunkowych. Inicjator wysyła SYN, odpowiadający wysyła ACK: rozpoczyna się jedno połączenie simpleks. „Następnie” respondent wysyła SYN, inicjator wysyła ACK: rozpoczyna się kolejne połączenie simpleks. Dwa połączenia simpleksowe tworzą jedną sesję dupleksową TCP, zgadzasz się? Logicznie więc w grę wchodzą cztery etapy; ale ponieważ flagi SYN i ACK są różnymi „polami” nagłówka TCP, można je ustawić jednocześnie - drugi i trzeci krok (z czterech) są połączone, więc technicznie istnieją trzy wymiany pakietów. Każde połączenie simpleks (pół) korzysta z dwukierunkowej wymiany, tak jak zaproponowałeś.
źródło
Jeśli serwer i klient chcą utworzyć połączenie, muszą potwierdzić cztery rzeczy:
Klient musi potwierdzić, że może odebrać pakiet z serwera
Klient musi coś potwierdzić: serwer może odbierać pakiet od klienta
Po tym
Client ------SYN-----> Server
reguła 1 zostaje potwierdzona.Następnie
Client <---ACK/SYN---- Server
reguły 2 i 3 zostają potwierdzone.Tak więc potrzebny jest trzeci pakiet do potwierdzenia reguły 4.
źródło
To wcale nie jest konieczne. Oczywiste jest, że krótka wiadomość powinna wymagać tylko jednego pakietu do serwera, który zawiera komunikat start + i jeden pakiet potwierdzający to.
Poprzednie odpowiedzi po prostu opisują system bez omawiania potrzeby losowych numerów sekwencji itp. Pierwotne pytanie dotyczyło samej konstrukcji TCP - oczywiście jeśli używasz protokołu TCP, potrzebujesz trzech wiadomości, ponieważ taki jest protokół. Ale dlaczego TCP został tak zaprojektowany?
Uważam, że pierwotnym pomysłem było to, że nie było rozróżnienia między klientami a serwerami. Obaj znali porty drugiego w dwukierunkowy sposób i każdy mógł rozpocząć rozmowę. A to wymagało synchronizacji itp.
Ale nie jest to oczywiście sposób, w jaki jest dziś używany. Serwer nasłuchuje na dobrze znanym porcie i „akceptuje”, numer portu klienta jest efemeryczny. Nie sądzę nawet, aby serwer, który czeka na „zaakceptuj”, mógł wysłać żądanie do innego na tym samym numerze portu klienta w normalnych systemach operacyjnych.
(Należy pamiętać, że dotyczy to dwukierunkowego inicjowania połączenia, co nigdy nie jest wykonywane dzisiaj. Jest to zupełnie inne niż wysyłanie dwukierunkowych wiadomości w dół po ustanowieniu połączenia).
Aby obejść nieefektywność TCP, używamy protokołów takich jak HTTP 1.1, które mogą ponownie wykorzystywać to samo połączenie dla wielu żądań, a tym samym unikać uzgadniania TCP, który nie był konieczny.
Ale HTTP 1.1 jest stosunkowo nowy. A SSL / TLS potrzebował sposobu na ponowne wykorzystanie sesji od samego początku ze względu na koszt algorytmów PKI. Tak więc ten protokół zawiera własny mechanizm ponownego wykorzystania sesji, który działa na Http 1.1, który działa na TCP.
Tak jest z oprogramowaniem. Krówki na kostkach, które w połączeniu dają zadowalający wynik.
źródło
Po przeczytaniu odpowiedzi Eddiego (zaakceptowanej jako poprawna), wciąż pozostaje pytanie, dlaczego 1. host nie może przypisać obu numerów ISN losowymi liczbami, a drugi po prostu je akceptuje. Prawdziwym powodem korzystania z 3-kierunkowego uzgadniania jest unikanie pół połączeń . Scenariusz połowy połączenia w przypadku dwukierunkowego uzgadniania:
1) Klient --- SYN -> Serwer
2) Klient zmienia zdanie i nie chce się już podłączać
3) Klient <-X-ACK-- Serwer // ACK został utracony
Serwer nie widzi ponownie SYN, więc uważa, że klient otrzymał potwierdzenie ACK i nawiązano połączenie. W rezultacie serwer ma połączenie, które nigdy nie zostanie zamknięte
źródło