L'handshake a 3 vie TCP funziona in questo modo:
Client ------SYN-----> Server
Client <---ACK/SYN---- Server
Client ------ACK-----> Server
Perché non solo questo?
Client ------SYN-----> Server
Client <-----ACK------ Server
L'handshake a 3 vie TCP funziona in questo modo:
Client ------SYN-----> Server
Client <---ACK/SYN---- Server
Client ------ACK-----> Server
Perché non solo questo?
Client ------SYN-----> Server
Client <-----ACK------ Server
Risposte:
Abbassa la stretta di mano in ciò che sta realmente facendo.
In TCP, le due parti tengono traccia di ciò che hanno inviato utilizzando un numero di sequenza. In effetti finisce per essere un conteggio dei byte in esecuzione di tutto ciò che è stato inviato. La parte ricevente può utilizzare il numero progressivo dell'altoparlante opposto per riconoscere ciò che ha ricevuto.
Ma il numero di sequenza non inizia da 0. Inizia da ISN (Initial Sequence Number), che è un valore scelto casualmente. E poiché TCP è una comunicazione bidirezionale, entrambe le parti possono "parlare", e quindi entrambe devono generare in modo casuale un ISN come numero di sequenza iniziale. Il che a sua volta significa che entrambe le parti devono comunicare all'altra parte il loro ISN iniziale.
Quindi finisci con questa sequenza di eventi per l'inizio di una conversazione TCP tra Alice e Bob:
Alice ---> Bob SYNchronize with my Initial Sequence Number of X
Alice <--- Bob I received your syn, I ACKnowledge that I am ready for [X+1]
Alice <--- Bob SYNchronize with my Initial Sequence Number of Y
Alice ---> Bob I received your syn, I ACKnowledge that I am ready for [Y+1]
Si noti che si stanno verificando quattro eventi:
In realtà, tuttavia, i due eventi centrali (n. 2 e n. 3) si verificano nello stesso pacchetto. Ciò che rende un pacchetto un SYN
o ACK
è semplicemente un flag binario attivato o disattivato all'interno di ciascuna intestazione TCP , quindi non c'è nulla che impedisca l'abilitazione di entrambi questi flag sullo stesso pacchetto. Quindi la stretta di mano a tre vie finisce per essere:
Bob <--- Alice SYN
Bob ---> Alice SYN ACK
Bob <--- Alice ACK
Notare le due istanze di "SYN" e "ACK", una per ciascuna, in entrambe le direzioni.
Quindi, per tornare alla tua domanda, perché non usare semplicemente una stretta di mano a due vie? La risposta breve è perché una stretta di mano a due vie consentirebbe a una sola parte di stabilire un ISN e l'altra parte di riconoscerlo. Ciò significa che solo una parte può inviare dati.
Ma TCP è un protocollo di comunicazione bidirezionale, il che significa che entrambe le estremità dovrebbero essere in grado di inviare dati in modo affidabile. Entrambe le parti devono stabilire un ISN ed entrambe le parti devono riconoscere l'ISN dell'altro.
Quindi, in effetti, quello che hai è esattamente la tua descrizione della stretta di mano a due vie, ma in ogni direzione . Quindi, si verificano quattro eventi. E ancora, le due bandiere centrali si trovano nello stesso pacchetto. Poiché tali tre pacchetti sono coinvolti in un processo completo di avvio della connessione TCP.
La stretta di mano a tre vie è necessario in quanto entrambe le parti devono syn chronize i loro numeri di sequenza di segmenti utilizzati durante la loro trasmissione. Per questo, ciascuno di essi manda (a sua volta) un segmento SYN con un numero di sequenza impostata su un valore casuale n , che poi viene ack nowledged dall'altra parte con un segmento ACK con un numero di sequenza impostato a n + 1 .
Eddie
commento alla sua risposta.
Affinché la connessione funzioni, ciascuna parte deve verificare di poter inviare pacchetti all'altro lato. L'unico modo per essere sicuri di aver ricevuto un pacchetto dall'altra parte è quello di ottenere un pacchetto da essi che, per definizione, non sarebbe stato inviato se il pacchetto inviato non fosse passato . TCP utilizza essenzialmente due tipi di messaggi per questo: SYN (per richiedere la prova che questo pacchetto è passato) e ACK (che viene inviato solo dopo che un SYN è passato, per dimostrare che il SYN è riuscito). In realtà c'è un terzo tipo di messaggio, ma ci arriveremo tra un momento.
Prima che inizi la connessione, nessuna delle due parti sa davvero nulla dell'altra. Il client invia un pacchetto SYN al server per richiedere la prova che i suoi messaggi possono passare . Ciò non dice nulla a nessuno, ma è il primo passo della stretta di mano.
Se passa il SYN, allora il server sa che il client può inviargli pacchetti, perché, beh, è appena successo. Ma ciò non dimostra che il server possa inviare i pacchetti indietro: i client possono inviare SYN per molte ragioni . Quindi il server deve rispedire due messaggi al client: un ACK (per dimostrare che il SYN è riuscito a passare) e un SYN (per richiedere un proprio ACK). TCP combina questi due messaggi in un unico messaggio SYN-ACK, se lo desideri, per ridurre il traffico di rete. Questo è il secondo passo della stretta di mano.
Poiché un SYN-ACK è un ACK, il client ora sa con certezza che può inviare pacchetti al server. E poiché un SYN-ACK è un SYN, sa anche che il server vuole la prova che questo messaggio è stato superato. Quindi restituisce un ACK: solo un semplice ACK questa volta, perché non ha più bisogno di prove che i suoi pacchetti possano passare. Questo è il passo finale della stretta di mano: il cliente ora sa che i pacchetti possono andare in entrambe le direzioni, e che il server è solo di conoscere questo numero (perché sa l'ACK passerà attraverso).
Una volta superato ACK, ora il server sa che può inviare pacchetti al client . Sa anche che il client lo sa, quindi può iniziare subito a inviare dati. La stretta di mano è completa. Abbiamo un buon canale.
Bene, a rigor di termini, non possiamo essere certi di avere un buon canale . Solo perché questa sequenza di pacchetti superata non garantisce rigorosamente che altri lo faranno. Non possiamo provarlo senza inviare un numero infinito di SYN e ACK, e quindi nient'altro sarebbe mai stato fatto, quindi questa non è davvero un'opzione pratica. Ma in pratica, tre passaggi risultano abbastanza buoni per la maggior parte degli scopi .
In realtà, una stretta di mano a 3 vie non è l'unico mezzo per stabilire una connessione TCP. È consentito anche lo scambio simultaneo di SYN: http://www.tcpipguide.com/free/t_TCPConnectionEstablishmentProcessTheThreeWayHandsh-4.htm
Potrebbe essere visto come una sorta di doppia stretta di mano a 2 vie.
La connessione TCP è bidirezionale. Ciò significa che in realtà è una coppia di connessioni unidirezionali. L'iniziatore invia SYN, il risponditore invia ACK: inizia una connessione simplex. "Quindi" il risponditore invia SYN, l'iniziatore invia ACK: inizia un'altra connessione simplex. Due connessioni simplex formano una sessione TCP duplex, d'accordo? Quindi logicamente ci sono quattro passaggi coinvolti; ma poiché i flag SYN e ACK sono diversi "campi" dell'intestazione TCP, possono essere impostati contemporaneamente: il secondo e il terzo passaggio (dei quattro) sono combinati, quindi tecnicamente ci sono tre scambi di pacchetti. Ogni connessione simplex (metà) utilizza lo scambio a 2 vie, come da te proposto.
Se Server e Client vogliono creare una connessione, devono confermare quattro cose:
Il cliente deve confermare che può ricevere il pacchetto dal server
Il client deve confermare una cosa: il server può ricevere il pacchetto dal client
Dopo Client ------SYN-----> Server
, la regola 1 è confermata.
Successivamente Client <---ACK/SYN---- Server
, le regole 2 e 3 sono confermate.
Quindi, è necessario un terzo pacchetto per confermare la regola 4.
Non è affatto necessario. È ovvio che un breve messaggio dovrebbe richiedere solo un pacchetto al server che include il messaggio start + e un pacchetto che lo riconosca.
Le risposte precedenti descrivono semplicemente il sistema senza discutere la necessità di numeri di sequenza casuali ecc. In primo luogo. La domanda originale riguardava la progettazione del TCP stesso: ovviamente se si utilizza il protocollo TCP, sono necessari tre messaggi perché quello è il protocollo. Ma perché TCP è stato progettato in questo modo in primo luogo?
Credo che l'idea originale fosse che non ci fosse distinzione tra client e server. Entrambi conoscevano i porti dell'altro in modo bidirezionale e potevano iniziare la conversazione. E questo ha richiesto Syns ecc.
Ma questo non è, ovviamente, come viene utilizzato oggi. Il server è in ascolto su una porta ben nota e lo fa e "accetta", il numero di porta del client è effimero. Non penso nemmeno che sia possibile per un server in attesa di un "accetta" di inviare una richiesta a un altro sullo stesso numero di porta client nei normali sistemi operativi.
(Si noti che si tratta dell'attivazione bidirezionale della connessione, che non viene mai eseguita oggi. Ciò è molto diverso dall'invio di messaggi bidirezionali tramite una connessione una volta stabilita.)
Per aggirare l'inefficienza TCP, utilizziamo protocolli come HTTP 1.1 che possono riutilizzare la stessa connessione per più richieste, evitando così l'handshake TCP che non era necessario in primo luogo.
Ma Http 1.1 è relativamente nuovo. E SSL / TLS necessitava di un modo per riutilizzare la sessione dall'inizio a causa del costo degli algoritmi PKI. Quindi quel protocollo include il proprio meccanismo di riutilizzo della sessione che viene eseguito su Http 1.1 che funziona su TCP.
Questo è il modo con il software. Fudges su kludges che, combinati, producono un risultato accettabile.
Dopo aver letto la risposta di Eddie (accettata come corretta), ci sono ancora dubbi sul perché il 1 ° host non può assegnare entrambi gli ISN con numeri casuali e il 2 ° semplicemente accettarlo. La vera ragione dell'uso della stretta di mano a 3 vie è quella di evitare le mezze connessioni . Scenario di metà connessione nell'handshake a 2 vie:
1) Client --- SYN -> Server
2) Il client cambia idea e non vuole più connettersi
3) Client <-X-ACK-- Server // ACK è stato perso
Il server non vede rinviato SYN, quindi pensa che il client abbia ottenuto il suo ACK e che la connessione sia stabilita. Di conseguenza il server ha una connessione che non verrà mai chiusa