TCP si integra naturalmente nell'ambiente client/server (vedi Figura 10.1). Applicazione server ascolta(ascolta) le richieste di connessione in entrata. Ad esempio, i servizi WWW, File Transfer o Terminal Access ascoltano le richieste dei client. La comunicazione in TCP viene avviata dalle subroutine appropriate, che avviano la connessione al server (vedi capitolo 21 sull'interfaccia di programmazione socket).
Riso. 10.1. Il client chiama il server.
In realtà, il client può essere un altro server. Ad esempio, i server di posta possono connettersi ad altri server di posta per inoltrare messaggi di posta elettronica tra computer.
10.2 Concetti TCP
In quale forma le applicazioni dovrebbero inviare dati su TCP? In che modo TCP trasferisce i dati all'IP? In che modo i protocolli TCP di invio e ricezione identificano la connessione tra le applicazioni e gli elementi di dati necessari per implementarla? A tutte queste domande viene data risposta nelle sezioni seguenti, che descrivono i concetti di base del TCP.
10.2.1 Flussi di dati in ingresso e in uscita
Concettuale il modello di connessione presuppone che l'applicazione invii un flusso di dati all'applicazione peer. Allo stesso tempo, è in grado di ricevere un flusso di dati dal suo partner di connessione. TCP fornisce full duplex(full duplex) modalità di funzionamento in cui simultaneamente due flussi dati (vedi Figura 10.2).
![](https://i0.wp.com/redov.ru/kompyutery_i_internet/tcp_ip_arhitektura_protokoly_realizacija_vklyuchaja_ip_versii_6_i_ip_security/img_124.png)
Riso. 10.2. Le applicazioni scambiano flussi di dati.
10.2.2 Segmenti
TCP può trasformare il flusso di dati che esce dall'applicazione in una forma adatta al posizionamento in datagrammi. Come?
L'applicazione trasmette i dati in TCP e questo protocollo li inserisce buffer di uscita(invia buffer). Successivamente, TCP taglia blocchi di dati dal buffer e li invia, aggiungendo un'intestazione (in questo caso, segmenti- segmento). Nella fig. 10.3 mostra come i dati da buffer di uscita TCP è impacchettato in segmenti. TCP trasmette il segmento a IP per la consegna come datagramma separato. Il confezionamento dei dati in blocchi della lunghezza corretta garantisce che i dati vengano inviati in modo efficiente, quindi TCP attenderà fino a quando la quantità di dati corrispondente non appare nel buffer di output prima di creare un segmento.
![](https://i1.wp.com/redov.ru/kompyutery_i_internet/tcp_ip_arhitektura_protokoly_realizacija_vklyuchaja_ip_versii_6_i_ip_security/img_125.png)
Riso. 10.3 Creazione di un segmento TCP
10.2.3 Espulsione
Tuttavia, grandi quantità di dati sono spesso impossibili da applicare alle applicazioni del mondo reale. Ad esempio, quando un programma client dell'utente finale avvia una sessione interattiva con un server remoto, l'utente immette solo comandi (seguiti premendo il tasto Ritorno).
Il programma client dell'utente ha bisogno che TCP sappia dell'invio di dati all'host remoto e lo faccia immediatamente. In questo caso, utilizzare espulsione(spingere).
Se osservi le operazioni in una sessione interattiva, puoi trovare molti segmenti con pochi dati e, inoltre, si possono trovare irregolarità in quasi tutti i segmenti di dati. Tuttavia, il push non dovrebbe essere applicato durante i trasferimenti di file (ad eccezione dell'ultimo segmento) e TCP sarà in grado di comprimere i dati in modo più efficiente in segmenti.
10.2.4 Dati urgenti
Il modello di inoltro dell'applicazione presuppone l'applicazione di un flusso ordinato di byte che viaggia verso la destinazione. Facendo nuovamente riferimento all'esempio della sessione interattiva, supponiamo che l'utente abbia premuto il tasto Attenzione(attenzione) o rottura(interrompere). L'applicazione remota deve essere in grado di ignorare i byte di interferenza e rispondere alla sequenza di tasti il prima possibile.
Meccanismo dati urgenti(dati urgenti) contrassegna le informazioni speciali nel segmento come urgente. In questo modo, TCP informa il suo peer che il segmento contiene dati urgenti e può indicare dove si trova. Il partner deve inoltrare queste informazioni all'applicazione di destinazione il prima possibile.
10.2.5 Porte dell'applicazione
Il cliente deve identificare il servizio a cui vuole accedere. Questo viene fatto specificando l'indirizzo IP del servizio dell'host e il suo numero di porta TCP. Come con UDP, i numeri di porta TCP vanno da 0 a 65535. Le porte comprese nell'intervallo da 0 a 1023 sono indicate come note e vengono utilizzate per accedere ai servizi standard.
Diversi esempi di porte note e le loro applicazioni corrispondenti sono mostrati nella Tabella 10.1. Servizi Scartare(porta 9) e carica(porta 19) sono le versioni TCP dei servizi che già conosciamo da UDP. Ricorda che il traffico della porta 9 TCP è completamente isolato dal traffico della porta 9 UDP.
Tabella 10.1 Porte TCP comunemente note e relative applicazioni
Porta | Appendice | Descrizione |
---|---|---|
9 | Scartare | Cancellazione di tutti i dati in arrivo |
19 | carica | Generatore di simboli. Scambio di flussi di caratteri |
20 | Dati FTP | Porta di inoltro dati FTP |
21 | FTP | Porta per conversazione FTP |
23 | TELNET | Porta per registrazione Telnet remota |
25 | SMTP | porta SMTP |
110 | POP3 | Recupero del servizio di posta per personal computer |
119 | NNTP | Accesso alle notizie online |
E le porte utilizzate dai client? In rari casi, il client non funziona tramite una porta nota. Ma in tali situazioni, volendo aprire una connessione, spesso chiede al sistema operativo di assegnargli una porta inutilizzata e non riservata. Al termine della connessione, il cliente è obbligato a restituire questa porta, dopodiché la porta può essere riutilizzata da un altro cliente. Poiché ci sono più di 63.000 porte TCP nel pool di numeri non riservati, i limiti delle porte client possono essere ignorati.
10.2.6 indirizzi socket
Come già sappiamo, si chiama la combinazione di indirizzo IP e porta per la comunicazione presa. Una connessione TCP è completamente identificata dall'indirizzo del socket a ciascuna estremità di tale connessione. Nella fig. 10.4 mostra la connessione tra un client su socket (128.36.1.24, porta = 3358) e un server su socket (130.42.88.22, porta = 21).
![](https://i0.wp.com/redov.ru/kompyutery_i_internet/tcp_ip_arhitektura_protokoly_realizacija_vklyuchaja_ip_versii_6_i_ip_security/img_126.png)
Riso. 10.4. Indirizzi socket
Ogni intestazione del datagramma contiene gli indirizzi IP di origine e di destinazione. Si vedrà in seguito che i numeri delle porte di origine e destinazione sono indicati nell'intestazione del segmento TCP.
In genere, un server è in grado di gestire più client contemporaneamente. Indirizzi socket univoci di un server vengono assegnati simultaneamente a tutti i suoi client (vedere la Figura 10.5).
![](https://i0.wp.com/redov.ru/kompyutery_i_internet/tcp_ip_arhitektura_protokoly_realizacija_vklyuchaja_ip_versii_6_i_ip_security/img_127.jpeg)
Riso. 10.5. Più client connessi agli indirizzi socket del server
Poiché un datagramma contiene un segmento di connessione TCP identificato da indirizzi IP e porte, è molto facile per un server tenere traccia di più connessioni client.
10.3 Meccanismo di affidabilità TCP
In questa sezione, esamineremo il meccanismo TCP utilizzato per fornire dati in modo affidabile mantenendo l'ordine di inoltro ed evitando perdite o duplicazioni.
10.3.1 Numerazione e conferma
TCP utilizza la numerazione e il riconoscimento (ACK) per garantire un trasferimento dati affidabile. Lo schema di numerazione TCP è alquanto insolito: ogni connessione inoltrata ottettoè considerato come avente un numero progressivo. L'intestazione del segmento TCP contiene il numero di sequenza il primo ottetto di dati di questo segmento.
Il destinatario è tenuto a confermare la ricezione dei dati. Se non arriva alcun ACK entro l'intervallo di timeout, i dati vengono ritrasmessi. Questo metodo si chiama riconoscimento positivo con relè(riconoscimento positivo con ritrasmissione).
Il TCP ricevitore monitora da vicino i numeri di sequenza in entrata per garantire che i dati vengano ricevuti in modo coerente e che non vi siano parti mancanti. Poiché gli ACK possono essere persi o ritardati casualmente, i segmenti duplicati possono arrivare al destinatario. I numeri di sequenza consentono di identificare i dati duplicati che vengono poi scartati.
Nella fig. 10.6 mostra uno sguardo semplificato al timeout e alla ritrasmissione TCP.
![](https://i1.wp.com/redov.ru/kompyutery_i_internet/tcp_ip_arhitektura_protokoly_realizacija_vklyuchaja_ip_versii_6_i_ip_security/img_128.png)
Riso. 10.6. Timeout e ritrasmissione in TCP
10.3.2 Campi porta, sequenza e ACK nell'intestazione TCP
Come mostrato in fig. 10.7, i primi campi dell'intestazione TCP forniscono spazio per le porte di origine e destinazione, il numero di sequenza del primo byte di dati incorporati e un ACK uguale al numero di sequenza prossimo byte previsto dall'altra parte. In altre parole, se TCP riceve tutti i byte fino al 30° dal suo peer, questo campo avrà il valore 31, indicando il segmento da inoltrare.
![](https://i2.wp.com/redov.ru/kompyutery_i_internet/tcp_ip_arhitektura_protokoly_realizacija_vklyuchaja_ip_versii_6_i_ip_security/img_129.png)
Riso. 10.7. Valori iniziali nei campi di intestazione TCP
Va notato un piccolo dettaglio. Supponiamo che TCP abbia inviato byte da 1 a 50 o più, non ci sono dati da inviare. Se i dati vengono ricevuti da un partner, TCP è obbligato a confermare la ricezione, per la quale invierà un'intestazione senza dati ad essa collegati. Naturalmente, questa intestazione contiene il valore ACK. Il campo sequenza contiene il valore 51, es. il numero del byte successivo che intende inviare TCP. Quando TCP invia i dati successivi, anche la nuova intestazione TCP avrà un valore di 51 nel campo della sequenza.
10.4 Stabilire una connessione
Come si connettono tra loro le due applicazioni? Prima della comunicazione, ciascuno di essi chiama una subroutine per formare un blocco di memoria che verrà utilizzato per memorizzare i parametri TCP e IP di questa connessione, ad esempio indirizzi socket, numero di sequenza corrente, valore iniziale della durata, ecc.
L'applicazione server attende la comparsa di un client, il quale, volendo accedere al server, invia una richiesta per composto(connect) identificando l'indirizzo IP e la porta del server.
C'è una particolarità tecnica. Ogni lato inizia la numerazione di ogni byte non con uno, ma con numero di sequenza casuale(di seguito scopriremo perché questo è fatto). La specifica originale consiglia: generare un numero di sequenza iniziale basato su un timer esterno a 32 bit che aumenta di circa ogni 4 μs.
10.4.1 Script di connessione
La procedura di connessione viene spesso definita handshake a tre vie perché vengono scambiati tre messaggi — SYN, SYN e ACK — per stabilire una connessione.
Durante la configurazione della connessione, i partner si scambiano tre importanti informazioni:
1. La quantità di spazio nel buffer per la ricezione dei dati
2. La quantità massima di dati trasportati nel segmento in entrata
3. Numero di sequenza iniziale utilizzato per i dati in uscita
Notare che ogni lato applica le operazioni 1 e 2 per indicare i limiti entro i quali la controparte opererà. Un personal computer può avere un piccolo buffer di ricezione e un supercomputer può avere un enorme buffer. La struttura della memoria di un personal computer può limitare le porzioni di dati in ingresso a 1 KB e il supercomputer è controllato con segmenti di grandi dimensioni.
La capacità di controllare come l'altra parte invia i dati è una proprietà importante per la scalabilità TCP/IP.
Nella fig. 10.8 mostra un esempio di uno script di connessione. Vengono presentati numeri sequenziali iniziali molto semplici per non sovraccaricare il disegno. Si noti che in questa figura il client è in grado di ricevere segmenti più grandi rispetto al server.
![](https://i2.wp.com/redov.ru/kompyutery_i_internet/tcp_ip_arhitektura_protokoly_realizacija_vklyuchaja_ip_versii_6_i_ip_security/img_130.png)
Riso. 10.8. Stabilire una connessione
Vengono eseguite le seguenti operazioni:
1. Il server è inizializzato e diventa pronto per connettersi ai client (questo stato è chiamato aperto passivo).
2. Il client chiede a TCP di aprire una connessione al server all'indirizzo IP e alla porta specificati (questo stato è chiamato attivo aperto).
3. Il client TCP riceve il numero di sequenza iniziale (in questo esempio - 1000) e invia segmento di sincronizzazione(sincronizza il segmento - SYN). Questo segmento contiene il numero di sequenza, la dimensione della finestra di ricezione (4K) e il segmento più grande che il client può accettare (1460 byte).
4. Quando arriva un SYN, il server TCP riceve mio numero di sequenza iniziale (3000). Invia un segmento SYN contenente un numero di sequenza iniziale (3000), ACK 1001 (che significa che il primo byte inviato dal client è numerato 1001), la dimensione della finestra di ricezione (4K) e il segmento più grande che il server può ricevere (1024 byte ).
5. Il client TCP, dopo aver ricevuto un messaggio SYN/ACK dal server, restituisce ACK 3001 (il primo byte dei dati inviati dal server deve essere numerato 3001).
6. Il client TCP indica alla sua applicazione di aprire una connessione.
7. Il server TCP, ricevuto un messaggio ACK dal client TCP, informa la sua applicazione dell'apertura della connessione.
Il client e il server annunciano le loro regole per i dati ricevuti, sincronizzano i loro numeri di sequenza e si preparano allo scambio di dati. La specifica TCP consente anche un altro scenario (non di grande successo) in cui le applicazioni peer si aprono attivamente l'una con l'altra contemporaneamente.
10.4.2 Impostazione dei valori dei parametri IP
La richiesta di connessione dell'applicazione può anche specificare i parametri per i datagrammi IP che trasporteranno i dati per quella connessione. Se non viene specificato alcun valore di parametro specifico, viene utilizzato il valore predefinito.
Ad esempio, un'applicazione può selezionare il valore desiderato per la priorità IP o il tipo di servizio. Poiché ciascuna delle parti collegate imposta in modo indipendente la propria priorità e il tipo di servizio, in teoria questi valori possono differire per le diverse direzioni dei flussi di dati. Di norma, in pratica, vengono utilizzati gli stessi valori per ciascuna direzione di scambio.
Quando un'applicazione utilizza opzioni di sicurezza per agenzie governative o militari, ciascuno degli endpoint di connessione deve utilizzare gli stessi livelli di sicurezza, altrimenti la connessione non verrà stabilita.
10.5 Trasferimento dati
Il trasferimento dei dati inizia dopo il completamento della conferma in tre fasi della creazione della connessione (vedi Fig. 10.9). Lo standard TCP consente di includere dati normali nei segmenti di riconoscimento, ma non verranno consegnati all'applicazione fino al completamento della connessione. Per facilitare la numerazione, vengono utilizzati messaggi di 1000 byte. Ogni segmento di intestazione TCP ha un campo ACK che identifica il numero di sequenza del byte che dovrebbe essere ricevuto dal peer sulla connessione..
![](https://i0.wp.com/redov.ru/kompyutery_i_internet/tcp_ip_arhitektura_protokoly_realizacija_vklyuchaja_ip_versii_6_i_ip_security/img_131.png)
Riso. 10.9. Flusso di dati semplice e ACK
Il primo segmento inviato dal client contiene byte da 1001 a 2000. Il suo campo ACK dovrebbe contenere il valore 3001, che indica il numero di sequenza del byte che dovrebbe essere ricevuto dal server.
Il server risponde al client con un segmento contenente 1000 byte di dati (a partire da 3001). Il suo campo ACK dell'intestazione TCP indicherà che i byte da 1001 a 2000 sono già stati ricevuti con successo, quindi il successivo numero di sequenza del segmento previsto dovrebbe essere 2001.
Il client quindi invia i segmenti che iniziano con i byte 2001, 3001 e 4001 in quell'ordine. Si noti che il client non si aspetta un ACK dopo ciascuno dei segmenti inviati. I dati vengono inviati al partner fino a quando il suo spazio nel buffer non è pieno (vedremo di seguito che il destinatario può indicare in modo molto accurato la quantità di dati che gli sono stati inviati).
Il server conserva la larghezza di banda utilizzando un singolo ACK per indicare l'inoltro riuscito di tutti i segmenti.
Nella fig. 10.10 mostra il trasferimento dei dati quando il primo segmento viene perso. Allo scadere del timeout, il segmento viene ritrasmesso. Nota che dopo aver ricevuto il segmento perso, il destinatario invia un ACK confermando che entrambi i segmenti sono stati inviati.
![](https://i0.wp.com/redov.ru/kompyutery_i_internet/tcp_ip_arhitektura_protokoly_realizacija_vklyuchaja_ip_versii_6_i_ip_security/img_132.png)
Riso. 10.10. Perdita e ritrasmissione dei dati
10.6 Chiusura di una connessione
La normale terminazione di una connessione viene eseguita utilizzando la stessa procedura di triplo handshake di quando si apre una connessione. Ciascuna delle parti può iniziare a chiudere la connessione nel seguente scenario:
UN:
B:"Buono".
V:"Ho finito anch'io il lavoro."
UN:"Buono".
È accettabile anche il seguente scenario (sebbene sia usato raramente):
UN:"Ho finito. Non ci sono più dati da inviare."
V:"Bene. Tuttavia, ci sono alcuni dati..."
V:"Ho finito anch'io il lavoro."
UN:"Buono".
Nell'esempio seguente, la connessione chiude il server, come spesso accade per le comunicazioni client/server. In questo caso, dopo che l'utente è entrato nella sessione telnet comandi di logout il server avvia una richiesta per chiudere la connessione. Nella situazione mostrata in Fig. 10.11, vengono eseguite le seguenti azioni:
1. Un'applicazione sul server dice a TCP di chiudere la connessione.
2. Il server TCP invia un Segmento Finale (FIN) informando il suo peer che non ci sono più dati da inviare.
3. Il TCP del client invia un ACK sul segmento FIN.
4. Il TCP del client dice alla sua applicazione che il server vuole chiudere la connessione.
5. L'applicazione client dice al suo TCP di chiudere la connessione.
6. Il TCP del client invia un messaggio FIN.
7. Il server TCP riceve il FIN dal client e risponde con un messaggio ACK.
8. Il server TCP ordina alla sua applicazione di chiudere la connessione.
![](https://i0.wp.com/redov.ru/kompyutery_i_internet/tcp_ip_arhitektura_protokoly_realizacija_vklyuchaja_ip_versii_6_i_ip_security/img_133.png)
Riso. 10.11. Chiusura di una connessione
Entrambi i lati possono iniziare a chiudersi contemporaneamente. In questo caso, la normale chiusura della connessione viene completata dopo che ogni partner invia un messaggio ACK.
10.6.1 Terminazione improvvisa
Ciascuna delle parti può richiedere la chiusura brusca del collegamento. Ciò è accettabile quando un'applicazione desidera terminare una connessione o quando TCP incontra un serio problema di comunicazione che non può risolvere da solo. La terminazione brusca viene richiesta inviando uno o più messaggi di reset al peer, come indicato da un flag specifico nell'intestazione TCP.
10.7 Controllo del flusso
Il ricevitore TCP viene caricato con il flusso di dati in entrata e determina la quantità di informazioni che può ricevere. Questa limitazione interessa il mittente TCP. La spiegazione di seguito per questo meccanismo è concettuale e gli sviluppatori possono implementarlo in diversi modi nei loro prodotti.
Durante l'impostazione della connessione, ogni partner alloca spazio per il buffer di input della connessione e lo notifica all'altro lato. In genere, la dimensione del buffer è espressa come numero intero delle dimensioni massime del segmento.
Il flusso di dati entra nel buffer di input e viene memorizzato lì prima di essere inviato all'applicazione (determinato dalla porta TCP). Nella fig. 10.12 mostra un buffer di input in grado di accettare 4KB.
![](https://i0.wp.com/redov.ru/kompyutery_i_internet/tcp_ip_arhitektura_protokoly_realizacija_vklyuchaja_ip_versii_6_i_ip_security/img_134.png)
Riso. 10.12. Finestra di ricezione del buffer di input
Lo spazio del buffer si riempie man mano che i dati arrivano. Quando l'applicazione ricevente recupera i dati dal buffer, lo spazio liberato diventa disponibile per i nuovi dati in ingresso.
10.7.1 Finestra di ricezione
Finestra di ricezione(finestra di ricezione) - qualsiasi spazio nel buffer di input non ancora occupato dai dati. I dati rimangono nel buffer di input finché non vengono consumati dall'applicazione di destinazione. Perché l'app non rileva subito i dati?
Un semplice scenario aiuterà a rispondere a questa domanda. Supponiamo che un client abbia caricato un file su un server FTP in esecuzione su un computer multiutente molto occupato. Il programma FTP deve quindi leggere i dati dal buffer e scriverli su disco. Quando il server esegue operazioni di I/O del disco, il programma attende il completamento di tali operazioni. A questo punto potrebbe avviarsi un altro programma (ad esempio, in base a una pianificazione) e mentre il programma FTP riparte, nel buffer arriveranno già i seguenti dati.
La finestra di ricezione si espande dall'ultimo byte riconosciuto fino alla fine del buffer. Nella fig. 10.12 in primo luogo, è disponibile l'intero buffer e quindi è disponibile una finestra di ricezione di 4 KB. All'arrivo del primo KB, la finestra di ricezione si ridurrà a 3 KB (per semplicità supporremo che ogni segmento sia 1 KB, anche se in pratica questo valore varia a seconda delle esigenze dell'applicazione). L'arrivo dei successivi due segmenti da 1 KB ridurrà la finestra di ricezione a 1 KB.
Ogni ACK inviato dal ricevitore contiene informazioni sullo stato corrente della finestra di ricezione, a seconda di quale è regolato il flusso di dati dalla sorgente.
Per la maggior parte, la dimensione del buffer di input è impostata al momento dell'avvio della connessione, sebbene lo standard TCP non specifichi come gestire questo buffer. Il buffer di input può aumentare o diminuire per fornire feedback al mittente.
Cosa succede se un segmento in entrata può essere posizionato nella finestra di ricezione, ma non è arrivato in ordine? Si presume generalmente che tutte le implementazioni memorizzino i dati in ingresso nella finestra di ricezione e inviino un riconoscimento (ACK) solo per un intero blocco contiguo di più segmenti. Questo è il metodo corretto, perché altrimenti l'eliminazione dei dati non ordinati ridurrà notevolmente le prestazioni.
10.7.2 Finestra di invio
Un sistema che trasmette dati deve tenere traccia di due caratteristiche: quanti dati sono già stati inviati e riconosciuti e la dimensione attuale della finestra di ricezione del destinatario. Attivo spazio di spedizione(spazio di invio) si espande dal primo ottetto non riconosciuto a sinistra della finestra di ricezione corrente. Parte finestra usato da inviare, indica quanti dati aggiuntivi possono essere inviati al partner.
Il numero di sequenza iniziale e la dimensione iniziale della finestra di ricezione vengono impostati durante l'impostazione della connessione. Riso. 10.13 illustra alcune delle caratteristiche del meccanismo di trasferimento dei dati.
1. Il mittente inizia con una finestra di invio di 4 KB.
2. Il mittente invia 1 KB. Una copia di questi dati viene conservata fino alla ricezione di un riconoscimento (ACK), poiché potrebbe essere necessario ritrasmetterli.
3. Arriva il messaggio ACK per il primo KB e vengono inviati i successivi 2 KB di dati. Il risultato è mostrato nella terza parte dall'alto della Fig. 10.13. L'archiviazione di 2 KB continua.
4. Infine, arriva un ACK per tutti i dati trasmessi (cioè tutti ricevuti dal ricevitore). ACK ripristina la dimensione della finestra di invio a 4K.
![](https://i1.wp.com/redov.ru/kompyutery_i_internet/tcp_ip_arhitektura_protokoly_realizacija_vklyuchaja_ip_versii_6_i_ip_security/img_135.png)
Riso. 10.13. Invia finestra
Da segnalare alcune caratteristiche interessanti:
S Il mittente non attende un ACK per ciascuno dei segmenti di dati che invia. L'unica limitazione al trasferimento è la dimensione della finestra di ricezione (ad esempio, il mittente deve inviare solo segmenti a byte singolo 4K).
S Supponiamo che il mittente invii dati in diversi segmenti molto brevi (ad esempio 80 byte). In questo caso, i dati possono essere riformattati per una trasmissione più efficiente (ad esempio, in un singolo segmento).
10.8 Intestazione TCP
Nella fig. 10.14 mostra il formato del segmento (intestazione TCP e dati). L'intestazione inizia con gli ID delle porte di origine e di destinazione. Prossimo campo successivo numero di serie(numero di sequenza) indica la posizione nel flusso di dati in uscita che occupa questo segmento. Campo ACK(riconoscimento) contiene informazioni sul segmento successivo previsto che appaia nel flusso di dati di input.
![](https://i2.wp.com/redov.ru/kompyutery_i_internet/tcp_ip_arhitektura_protokoly_realizacija_vklyuchaja_ip_versii_6_i_ip_security/img_136.png)
Riso. 10.14. Segmento TCP
Ci sono sei bandiere:
Campo distorsione dei dati(Data Offset) contiene la dimensione dell'intestazione TCP in parole a 32 bit. L'intestazione TCP deve terminare a un limite di 32 bit.
10.8.1 Opzione per la dimensione massima del segmento
Parametro "dimensione massima del segmento"(dimensione massima del segmento - MSS) viene utilizzato per pubblicizzare il più grande blocco di dati che può essere ricevuto ed elaborato dal sistema. Tuttavia, il titolo è un po' impreciso. Di solito in TCP segmento trattato come intestazione più dati. ma dimensione massima del segmento definito come:
Il datagramma più grande che puoi accettare è 40
In altre parole, il MSS riflette il più grande carico utile nel ricevitore con una lunghezza di intestazioni TCP e IP di 20 byte. Se sono presenti parametri aggiuntivi, la loro lunghezza deve essere sottratta dalla dimensione totale. Pertanto, la quantità di dati che può essere inviata in un segmento è definita come:
Valore dichiarato MSS + 40 - (somma delle lunghezze delle intestazioni TCP e IP)
I peer in genere scambiano valori MSS nei messaggi SYN iniziali quando viene aperta una connessione. Se il sistema non annuncia una dimensione massima del segmento, viene utilizzato il valore predefinito di 536 byte.
La dimensione del segmento massimo è codificata con un preambolo di 2 byte seguito da un valore di 2 byte, ad es. il valore più grande sarà 2 16 -1 (65 535 byte).
MSS impone un limite rigido ai dati inviati a TCP: il destinatario non sarà in grado di elaborare valori grandi. Tuttavia, il mittente utilizza i segmenti più piccola, perché la MTU lungo il percorso è determinata anche per la connessione.
10.8.2 Utilizzo dei campi di intestazione in una richiesta di connessione
Il primo segmento inviato per aprire una connessione ha un flag SYN di 1 e un flag ACK di 0. Il SYN iniziale è l'unico un segmento che ha un campo ACK di 0. Si noti che la sicurezza utilizza questa funzionalità per rilevare le richieste in entrata per una sessione TCP.
Campo numero di serie contiene numero di sequenza iniziale(numero di sequenza iniziale), campo finestra - dimensione iniziale finestra di ricezione. L'unico parametro TCP attualmente definito è la dimensione massima del segmento (se non specificata, il valore predefinito è 536 byte) che TCP si aspetta di ricevere. Questo valore è lungo 32 bit ed è solitamente presente nella richiesta di connessione nel campo opzioni(Opzione). L'intestazione TCP contenente il valore MSS è lunga 24 byte.
10.8.3 Utilizzo dei campi di intestazione nella risposta di connessione
In una risposta di abilitazione a una richiesta di connessione, entrambi i flag (SYN e ACK) sono uguali a 1. Il sistema che risponde indica il numero di sequenza iniziale nel campo corrispondente e la dimensione della finestra di ricezione nel campo Finestra... La dimensione massima del segmento che il destinatario desidera utilizzare si trova solitamente nella risposta alla richiesta di connessione (nella sezione opzioni). Tale valore può essere diverso dal valore del richiedente la connessione, es. possono essere utilizzati due valori diversi.
È possibile rifiutare una richiesta di connessione specificando un flag di ripristino (RST) con valore 1 nella risposta.
10.8.4 Selezione del numero di sequenza iniziale
La specifica TCP presuppone che durante l'instaurazione della connessione, ciascuna parte scelga numero di sequenza iniziale(al valore corrente del timer interno a 32 bit). Come si fa?
Immagina cosa succede quando il sistema va in crash. Supponiamo che l'utente abbia aperto una connessione appena prima dell'arresto anomalo e abbia inviato una piccola quantità di dati. Dopo il ripristino, il sistema non ricorda più nulla di ciò che è stato fatto prima dell'arresto anomalo, comprese le connessioni già in esecuzione e i numeri di porta assegnati. L'utente ristabilisce la connessione. I numeri di porta non corrispondono alle assegnazioni originali e alcuni di essi potrebbero essere già in uso da altre connessioni stabilite pochi secondi prima dell'arresto anomalo.
Pertanto, l'altra parte alla fine della connessione potrebbe non sapere che il suo partner ha attraversato un crollo e il suo lavoro è stato quindi ripristinato. Tutto ciò porterà a gravi interruzioni, soprattutto quando occorre molto tempo prima che i vecchi dati viaggino sulla rete e si mescolino con i dati della connessione appena creata. La selezione del timer del nuovo avvio elimina tali problemi. I vecchi dati avranno una numerazione diversa rispetto all'intervallo di numeri di sequenza della nuova connessione. Gli hacker, quando falsificano l'indirizzo IP di origine per un host attendibile, tentano di accedere ai computer specificando nel messaggio un numero di sequenza iniziale prevedibile. Una funzione hash crittografica basata su chiavi interne è il modo migliore per selezionare numeri di inizializzazione sicuri.
10.8.5 Uso comune dei campi
Quando si prepara l'intestazione TCP per la trasmissione, nel campo viene indicato il numero di sequenza del primo ottetto dei dati trasmessi numero sequenziale(Sequenza di numeri).
Il successivo numero di ottetto atteso dal partner di connessione viene inserito nel campo conferma(Numero di riconoscimento) quando il bit ACK è impostato su 1. Campo finestra(Finestra) è per la dimensione corrente della finestra di ricezione. Questo campo contiene il numero di byte dal numero di conferma che può essere accettato... Si noti che questo valore consente un controllo preciso del flusso di dati. Utilizzando questo valore, il partner indica lo stato reale della finestra di ricezione durante la sessione di scambio.
Se l'applicazione punta a un'operazione push TCP, il flag PUSH è impostato su 1. Il TCP ricevente DEVE rispondere a questo flag consegnando rapidamente i dati all'applicazione non appena il mittente desidera inviarli.
Il flag URGENT, se impostato a 1, implica il trasferimento di dati urgenti e il puntatore corrispondente DEVE fare riferimento all'ultimo ottetto di dati urgenti. Un uso tipico per i dati urgenti è inviare segnali di annullamento o interruzione dal terminale.
I dati urgenti vengono spesso chiamati informazioni fuori banda(fuori banda). Tuttavia, questo termine è impreciso. I dati accelerati vengono inviati su un normale flusso TCP, sebbene alcune implementazioni possano avere meccanismi speciali per dire all'applicazione di ricevere dati urgenti e l'applicazione deve controllare il contenuto dei dati urgenti prima che arrivino tutti i byte del messaggio.
Il flag RESET è impostato su 1 per interrompere la connessione. Lo stesso flag viene impostato nella risposta quando arriva un segmento che non è associato a nessuna delle connessioni TCP correnti.
FIN è impostato su 1 per i messaggi di chiusura della connessione.
10.8.6 Checksum
Il checksum IP è solo per l'intestazione IP e il checksum TCP viene calcolato per l'intero segmento così come per la pseudo-intestazione generata dall'intestazione IP. Quando si calcola il checksum TCP, il campo corrispondente è impostato su 0. In fig. 10.15 mostra una pseudo-intestazione molto simile a quella utilizzata nel checksum UDP.
![](https://i1.wp.com/redov.ru/kompyutery_i_internet/tcp_ip_arhitektura_protokoly_realizacija_vklyuchaja_ip_versii_6_i_ip_security/img_137.png)
Riso. 10:15 Il campo pseudo-intestazione è incluso nel checksum TCP
La lunghezza TCP viene calcolata aggiungendo la lunghezza dell'intestazione TCP alla lunghezza dei dati. Il checksum TCP è obbligatorio, non come UDP. Il checksum del segmento ricevuto viene prima calcolato dal ricevitore e quindi confrontato con il contenuto del campo checksum dell'intestazione TCP. Se i valori non corrispondono, il segmento viene scartato.
10.9 Segmento TCP di esempio
Riso. 10.16, protocollo dell'analizzatore annusare da Network General, è una sequenza di segmenti TCP. I primi tre segmenti stabiliscono una connessione tra il client e il server Telnet... L'ultimo segmento trasporta 12 byte di dati.
![](https://i2.wp.com/redov.ru/kompyutery_i_internet/tcp_ip_arhitektura_protokoly_realizacija_vklyuchaja_ip_versii_6_i_ip_security/img_138.png)
Riso. 10.16. Visualizzazione dell'intestazione TCP tramite l'analizzatore sniffer
Analizzatore annusare traduce la maggior parte dei valori in decimale. Tuttavia, i valori dei flag vengono emessi come esadecimali. Il flag con il valore 12 è 010010. Il checksum viene visualizzato anche in forma esadecimale.
10.10 Supporto alla sessione
10.10.1 Sondaggio finestre
Un mittente veloce e un destinatario lento possono formare una finestra di ricezione di 0 byte. Questo risultato si chiama chiudendo la finestra(chiudi la finestra). Quando c'è spazio libero per aggiornare la dimensione della finestra di ricezione, viene utilizzato ACK. Tuttavia, se tale messaggio viene perso, entrambe le parti dovranno attendere a tempo indeterminato.
Per evitare questa situazione, il mittente imposta timer memorizzato(temporizzatore persistente) quando la finestra è chiusa. Il valore del timer è il timeout di ritrasmissione. Alla fine del timer, viene inviato un segmento al partner finestra che suona(window probe; alcune implementazioni includono anche i dati). Il sondaggio fa sì che il peer invii un ACK che riporta lo stato corrente della finestra.
Se la finestra è ancora di dimensione zero, il valore del timer memorizzato viene raddoppiato. Questo processo viene ripetuto finché il timer non raggiunge un massimo di 60 secondi. TCP continuerà a inviare messaggi probe ogni 60 secondi, fino all'apertura della finestra, fino al termine del processo da parte dell'utente o fino al timeout dell'applicazione.
10.11 Disconnessione
10.11.1 Timeout
Il partner di collegamento può andare in crash o essere completamente interrotto a causa di un gateway o di un'interruzione della comunicazione. Esistono diversi meccanismi per impedire al TCP di inviare nuovamente i dati.
Al raggiungimento della prima soglia di ritrasmissione (inoltro), TCP ordina all'IP di verificare il router guasto e contemporaneamente informa l'applicazione del problema. TCP continua a inviare dati fino a quando non viene raggiunto il secondo valore limite e solo allora termina la connessione.
Naturalmente, prima che ciò accada, potrebbe arrivare un messaggio ICMP che indica che la destinazione è irraggiungibile per qualche motivo. In alcune implementazioni, anche in questo caso, TCP continuerà a tentare di raggiungere la destinazione fino alla scadenza dell'intervallo di timeout (dopo il quale il problema potrebbe essere risolto). Successivamente, l'applicazione viene informata che la destinazione è irraggiungibile.
L'applicazione può impostare il proprio timeout di consegna dei dati ed eseguire le proprie operazioni alla fine di questo intervallo. La connessione è generalmente interrotta.
10.11.2 Mantenimento della connessione
Quando una connessione incompleta ha dati da trasferire per lungo tempo, ottiene lo stato inattivo. Durante il periodo di inattività possono verificarsi arresti anomali della rete o disconnessioni di collegamenti fisici. Non appena la rete tornerà operativa, i partner continueranno a scambiare dati senza interrompere la sessione di comunicazione. Questa strategia era in linea con i requisiti del Dipartimento della Difesa.
Tuttavia, qualsiasi connessione, attiva o inattiva, occupa molta memoria del computer. Alcuni amministratori devono restituire le risorse inutilizzate ai sistemi. Pertanto, molte implementazioni TCP sono in grado di inviare un messaggio su mantenendo la connessione(keep-alive) test delle connessioni inattive. Tali messaggi vengono periodicamente inviati al partner per verificarne l'esistenza in rete. I messaggi ACK dovrebbero essere ricevuti in risposta. L'uso dei messaggi keepalive è facoltativo. Se il sistema dispone di questa capacità, l'applicazione può annullarla con i propri mezzi. Periodo stimato predefinito il timeout per mantenere una connessione è di due ore intere!
Ricordiamo che l'applicazione può impostare un proprio timer, in base al quale, al proprio livello, deciderà di interrompere la connessione.
10.12 Prestazione
Quanto è efficiente il TCP? Molti fattori influenzano le prestazioni delle risorse, di cui la memoria e la larghezza di banda sono i principali (vedere la Figura 10.17).
![](https://i1.wp.com/redov.ru/kompyutery_i_internet/tcp_ip_arhitektura_protokoly_realizacija_vklyuchaja_ip_versii_6_i_ip_security/img_139.png)
Riso. 10.17. Fattori di prestazione TCP
La larghezza di banda e la latenza nella rete fisica in uso limiteranno notevolmente la larghezza di banda. La scarsa qualità del trasferimento dei dati si traduce in un grande volume di datagrammi persi, che causa la ritrasmissione e, di conseguenza, riduce l'efficienza della larghezza di banda.
Il lato ricevente deve fornire spazio di buffer sufficiente per consentire al mittente di inviare dati senza interruzioni. Ciò è particolarmente importante per le reti ad alta latenza in cui c'è un lungo intervallo di tempo tra l'invio dei dati e la ricezione di un ACK (e quando si negozia una dimensione della finestra). Per mantenere un flusso di dati stabile dalla sorgente, il lato ricevente deve avere una finestra di almeno il prodotto della larghezza di banda e del ritardo.
Ad esempio, se la sorgente può inviare dati a una velocità di 10.000 byte/s, e impiega 2 secondi per restituire un ACK, allora dall'altra parte è necessario fornire una finestra di ricezione di almeno 20.000 byte, altrimenti il flusso di dati non sarà continuo. Un buffer di ricezione di 10.000 byte dimezzerà il throughput.
Un altro fattore importante per le prestazioni è la capacità dell'host di rispondere a eventi ad alta priorità ed eseguire rapidamente cambio di contesto, cioè. completare alcune operazioni e passare ad altre. L'host può supportare in modo interattivo molti utenti locali, processi batch in background e decine di connessioni di comunicazione simultanee. Il cambio di contesto consente di eseguire tutte queste operazioni nascondendo il carico sul sistema. Le implementazioni che integrano TCP/IP con il kernel del sistema operativo possono ridurre significativamente il sovraccarico dell'utilizzo del cambio di contesto.
Le risorse della CPU del computer sono necessarie per l'elaborazione delle intestazioni TCP. Se il processore non è in grado di calcolare rapidamente i checksum, rallenterà la velocità di trasferimento dei dati sulla rete.
Inoltre, gli sviluppatori dovrebbero considerare di semplificare la configurazione dei parametri TCP in modo che l'amministratore di rete possa personalizzarli in base alle proprie esigenze locali. Ad esempio, la capacità di regolare la dimensione del buffer per la larghezza di banda e la latenza di rete migliorerà notevolmente le prestazioni. Sfortunatamente, molte implementazioni non prestano sufficiente attenzione a questo problema e codificano i parametri di comunicazione.
Supponiamo che l'ambiente di rete sia perfetto: ci sono risorse sufficienti e il cambio di contesto è più veloce di quanto i cowboy tirino fuori i loro revolver. Otterrai prestazioni eccellenti?
Non sempre. Anche la qualità dello sviluppo del software TCP è importante. Molti problemi di prestazioni sono stati diagnosticati e risolti nel corso degli anni in varie implementazioni TCP. Il miglior software è RFC 1122, che definisce i requisiti del livello di comunicazione per gli host Internet.
Altrettanto importante è l'eccezione e l'applicazione degli algoritmi di Jacobson, Kern e Partridge (questi interessanti algoritmi saranno discussi in seguito).
Gli sviluppatori di software possono trarre vantaggi significativi creando programmi che eliminano i trasferimenti non necessari di piccole quantità di dati e dispongono di timer integrati per liberare risorse di rete che non vengono attualmente utilizzate.
10.13 Algoritmi per migliorare le prestazioni
Passando alla parte piuttosto complessa del TCP, esamineremo i meccanismi per migliorare le prestazioni e risolvere i colli di bottiglia della larghezza di banda. Questa sezione tratta i seguenti problemi:
■ Avvio lento(avvio lento) impedisce l'utilizzo di una grande percentuale del traffico di rete per una nuova sessione, che può causare un sovraccarico.
■ Recupero da sindrome della finestra goffa(sindrome della finestra stupida) impedisce alle applicazioni mal progettate di sovraccaricare la rete di messaggi.
■ ACK ritardato(ACK ritardato) riduce la congestione riducendo il numero di messaggi di conferma di inoltro indipendenti.
■ Timeout di ritrasmissione calcolato(calcolando il timeout di ritrasmissione) si basa sulla negoziazione del tempo di sessione in tempo reale, riducendo le ritrasmissioni non necessarie, ma non causando grandi ritardi per gli scambi di dati realmente necessari.
■ Rallenta l'inoltro TCP quando sovraccarichi sulla rete consente ai router di tornare alla modalità originale e condividere le risorse di rete per tutte le sessioni.
■ Invio ACK duplicati(ACK duplicato) quando si riceve un segmento fuori sequenza, consente ai peer di inviare nuovamente prima che si verifichi il timeout.
10.13.1 Avvio lento
Se tutti gli elettrodomestici vengono accesi contemporaneamente a casa, si verificherà un sovraccarico della rete elettrica. Nelle reti di computer avvio lento impedisce che i fusibili di rete si brucino.
Una nuova connessione che attiva istantaneamente il trasferimento di grandi quantità di dati su una rete già caricata può causare problemi. L'idea alla base dell'avvio lento è garantire che la nuova connessione abbia un avvio corretto aumentando lentamente la velocità di trasferimento dei dati in base al carico effettivo sulla rete. Il mittente è limitato dalle dimensioni della finestra di caricamento, non dalla grande finestra di ricezione.
Finestra di caricamento(finestra di congestione) inizia con una dimensione di 1 segmento. Per ogni segmento con un ACK ricevuto con successo, la finestra di caricamento viene aumentata di 1 segmento finché rimane più piccola della finestra di ricezione. Se la rete non è sovraccarica, la finestra di caricamento raggiungerà gradualmente le dimensioni della finestra di ricezione. In condizioni di inoltro normali, queste finestre avranno le stesse dimensioni.
Nota che l'avvio lento non è così lento. Dopo il primo ACK, la dimensione della finestra di caricamento è pari a 2 segmenti e, dopo aver ricevuto con successo un ACK per due segmenti, la dimensione può aumentare a 8 segmenti. In altre parole, la dimensione della finestra cresce in modo esponenziale.
Supponiamo che invece di ricevere un ACK, si sia verificata una situazione di timeout. Il comportamento della finestra di caricamento in questo caso è discusso di seguito.
10.13.2 Sindrome della finestra senza indizi
Nelle prime implementazioni di TCP/IP, gli sviluppatori hanno affrontato il fenomeno sindrome della finestra goffa(Silly Window Syndrome - SWS), che si presentava abbastanza spesso. Per comprendere gli eventi che si verificano, considera il seguente scenario, che porta a conseguenze indesiderabili, ma è del tutto possibile:
1. L'applicazione di invio invia i dati rapidamente.
2. L'applicazione ricevente legge 1 byte di dati dal buffer di input (cioè lentamente).
3. Il buffer di input si riempie rapidamente dopo la lettura.
4. L'applicazione ricevente legge 1 byte e TCP invia un ACK che significa "Ho spazio libero per 1 byte di dati".
5. L'applicazione mittente invia un pacchetto TCP a 1 byte sulla rete.
6. Il TCP ricevente invia un ACK che significa "Grazie. Ho ricevuto un pacchetto e non ho più spazio libero".
7. L'applicazione ricevente legge di nuovo 1 byte e invia un ACK, e l'intero processo si ripete.
Un'applicazione di ricezione lenta attende a lungo l'arrivo dei dati e spinge costantemente le informazioni ricevute sul bordo sinistro della finestra, eseguendo un'operazione completamente inutile che genera traffico aggiuntivo sulla rete.
Le situazioni della vita reale, ovviamente, non sono così estreme. Un mittente veloce e un destinatario lento si scambieranno piccoli blocchi di dati (rispetto alla dimensione massima del segmento) e passeranno su una finestra di ricezione quasi piena. Nella fig. 10.18 mostra le condizioni per la comparsa della sindrome della "finestra sciocco".
![](https://i0.wp.com/redov.ru/kompyutery_i_internet/tcp_ip_arhitektura_protokoly_realizacija_vklyuchaja_ip_versii_6_i_ip_security/img_140.png)
Riso. 10.18. Ricevi il buffer della finestra con uno spazio libero molto ridotto
Questo problema non è difficile da risolvere. Non appena la finestra di ricezione si riduce al di sotto della dimensione di destinazione data, TCP inizia a ingannare il mittente. In questa situazione, TCP non dovrebbe puntare il mittente a aggiuntivo spazio nella finestra quando l'applicazione ricevente legge i dati dal buffer in piccoli blocchi. Invece, le risorse rilasciate dovrebbero essere mantenute segrete al mittente finché non ce ne sono a sufficienza. La dimensione consigliata è un segmento, a meno che l'intero buffer di input contenga un singolo segmento (in quest'ultimo caso viene utilizzata una dimensione pari alla metà del buffer). La dimensione del target da riportare da TCP può essere espressa come:
minimo (1/2 buffer di input, dimensione massima del segmento)
TCP inizia a barare quando la dimensione della finestra diventa inferiore a questa dimensione e dirà la verità quando la dimensione della finestra non è inferiore al valore ottenuto dalla formula. Si noti che non vi è alcun danno per il mittente perché l'applicazione ricevente non sarebbe ancora in grado di elaborare la maggior parte dei dati previsti.
La soluzione proposta può essere facilmente verificata nel caso precedente con un output ACK per ciascuno dei byte ricevuti. Lo stesso metodo è adatto anche nel caso in cui il buffer di input possa memorizzare più segmenti (come spesso accade nella pratica). Il mittente veloce riempirà il buffer di input, ma il destinatario indicherà che non ha spazio libero per accogliere le informazioni e non aprirà questa risorsa finché le sue dimensioni non raggiungeranno l'intero segmento.
10.13.3 Algoritmo di Nagle
Il mittente dovrebbe, indipendentemente dal destinatario, escludere la trasmissione di segmenti molto brevi, accumulando dati prima dell'invio. L'algoritmo di Nagle implementa un'idea molto semplice per ridurre il numero di brevi datagrammi inviati sulla rete.
L'algoritmo consiglia di ritardare il trasferimento dei dati (e il push) attendendo l'ACK dai dati trasmessi in precedenza. I dati accumulati vengono inviati dopo aver ricevuto un ACK su un'informazione inviata in precedenza, o dopo aver ricevuto dati della dimensione di un intero segmento per l'invio, o dopo la scadenza di un timeout. Questo algoritmo non deve essere utilizzato per applicazioni in tempo reale che devono inviare dati il più rapidamente possibile.
10.13.4 ACK ritardato
Un altro meccanismo di miglioramento delle prestazioni è il metodo di ritardo ACK. Riducendo il numero di ACK si riduce la quantità di larghezza di banda che può essere utilizzata per inoltrare altro traffico. Se il peer TCP ritarda leggermente l'invio dell'ACK, allora:
■ È possibile confermare la ricezione di più segmenti con un ACK.
■ L'applicazione ricevente è in grado di ricevere una certa quantità di dati entro l'intervallo di timeout; l'intestazione di output può essere inclusa nell'ACK e non ha bisogno di generare un messaggio separato.
Per evitare ritardi durante l'invio di un flusso di segmenti interi (ad esempio, durante lo scambio di file), è necessario inviare un ACK almeno per ogni secondo segmento completo.
Molte implementazioni utilizzano un timeout di 200 ms. Ma l'ACK ritardato non rallenta il tasso di cambio. Quando arriva un breve segmento, c'è ancora spazio libero sufficiente nel buffer di input per ricevere nuovi dati e il mittente può continuare a inviare (inoltre, la ritrasmissione è generalmente molto più lenta). Se arriva un intero segmento, devi rispondere ad esso con un messaggio ACK nello stesso secondo.
10.13.5 Timeout ritrasmissione
Dopo aver inviato il segmento, TCP imposta un timer e monitora l'arrivo dell'ACK. Se non viene ricevuto alcun ACK entro il periodo di timeout, TCP ritrasmette il segmento (relè). Tuttavia, quale dovrebbe essere il periodo di time-out?
Se è troppo breve, il mittente riempirà la rete con l'inoltro di segmenti non necessari che duplicano le informazioni già inviate. Un timeout troppo lungo ti impedirà di riparare rapidamente i segmenti che sono davvero cattivi durante il trasferimento, il che ridurrà il throughput.
Come faccio a scegliere la giusta quantità di tempo per un timeout? Un valore che va bene per una LAN ad alta velocità non va bene per una connessione remota multi-hit. Ciò significa che il principio di "un valore per tutte le condizioni" è chiaramente inadatto. Inoltre, anche per una connessione specifica esistente, le condizioni della rete possono cambiare e i ritardi possono aumentare o diminuire.
Algoritmi di Jacobson, Kern e Partridge (descritti negli articoli , Van Jacobson e Miglioramento delle stime dei tempi di andata e ritorno in protocolli di trasporto affidabili, Karn e Partridge) consentono al TCP di adattarsi alle mutevoli condizioni della rete. Questi algoritmi sono consigliati per l'uso in nuove implementazioni. Li tratteremo brevemente di seguito.
Il buon senso impone che la base migliore per stimare il tempo di timeout corretto per una particolare connessione possa essere tempo di ciclo(tempo di andata e ritorno) come intervallo tra l'invio dei dati e la ricezione della conferma della loro ricezione.
È possibile ottenere buone decisioni per le seguenti quantità dalle statistiche di base (vedere la Figura 10.19) che possono aiutare a calcolare il tempo di timeout. Tuttavia, non fare affidamento sulle medie, poiché più della metà delle stime sarà maggiore della media. Osservando un paio di deviazioni, è possibile ottenere stime più corrette, tenendo conto della distribuzione normale e riducendo i tempi di attesa di ritrasmissione troppo lunghi.
![](https://i2.wp.com/redov.ru/kompyutery_i_internet/tcp_ip_arhitektura_protokoly_realizacija_vklyuchaja_ip_versii_6_i_ip_security/img_141.png)
Riso. 10.19. Distribuzione dei tempi di ciclo
Non è necessaria una grande quantità di calcolo per ottenere stime matematiche formali delle deviazioni. È possibile utilizzare stime approssimative basate sul valore assoluto della differenza tra l'ultimo valore e la stima media:
Ultima deviazione = | Ultimo ciclo - Media |
Un altro fattore da considerare quando si calcola il timeout corretto è la variazione del tempo di ciclo dovuta alle condizioni attuali della rete. Quello che è successo sul web all'ultimo minuto è più importante di quello che è successo un'ora fa.
Supponiamo di calcolare una media di ciclo per una sessione molto lunga. Anche se la rete è stata inizialmente caricata leggermente e abbiamo determinato 1000 valori piccoli, si è verificato un aumento del traffico con un aumento significativo della latenza.
Ad esempio, se 1000 valori hanno dato una media di 170 unità, ma poi 50 valori sono stati misurati con una media di 282, allora la media attuale sarà:
170 × 1000/1050 + 282 × 50/1050 = 175
Più ragionevole sarebbe il valore tempo di ciclo livellato(Smoothed Round-Trip Time - SRTT), che tiene conto della priorità dei valori successivi:
Nuovo SRTT = (1 - α) × (vecchio SRTT) + α × Valore ultimo ciclo
Il valore α è compreso tra 0 e 1. aumentare a determina una maggiore influenza del tempo di ciclo corrente sulla media livellata. Poiché i computer possono dividere rapidamente per potenze di 2 spostando i numeri binari a destra, α viene sempre scelto come (1/2) n (di solito 1/8), quindi:
Nuovo SRTT = 7/8 × vecchio SRTT + 1/8 × Tempo dell'ultimo ciclo
La Tabella 10.2 mostra come la formula per SRTT si adegua al valore SRTT corrente di 230 quando un cambiamento nelle condizioni della rete determina un aumento progressivo del tempo di ciclo (supponendo che non si verifichi un timeout). I valori nella colonna 3 vengono utilizzati come valori nella colonna 1 per la riga successiva nella tabella (ovvero come il vecchio SRTT).
Tabella 10.2 Calcolo del tempo di ciclo livellato
Vecchio SRTT | RTT . più recente | (7/8) × (vecchio SRTT) + (1/8) × (RTT) |
---|---|---|
230.00 | 294 | 238.00 |
238.00 | 264 | 241.25 |
241.25 | 340 | 253.59 |
253.59 | 246 | 252.64 |
252.64 | 201 | 246.19 |
246.19 | 340 | 257.92 |
257.92 | 272 | 259.68 |
259.68 | 311 | 266.10 |
266.10 | 282 | 268.09 |
268.09 | 246 | 265.33 |
265.33 | 304 | 270.16 |
270.16 | 308 | 274.89 |
274.89 | 230 | 269.28 |
269.28 | 328 | 276.62 |
276.62 | 266 | 275.29 |
275.29 | 257 | 273.00 |
273.00 | 305 | 277.00 |
Ora viene la questione della scelta di un valore per il timeout di ritrasmissione. L'analisi dei tempi di ciclo rivela una deviazione significativa di questi valori dalla media attuale. Ha senso impostare un limite per l'entità delle deviazioni (deviazioni). Buoni valori per il timeout di ritrasmissione (chiamato Retransmission TimeOut - RTO negli standard RFC) sono dati dalla seguente formula con un vincolo di deviazione livellato (SDEV):
T = Timeout ritrasmissione = SRTT + 2 × SDEV
T = SRTT + 4 × SDEV
Per calcolare SDEV, determinare prima il valore assoluto della deviazione corrente:
DEV = | Tempo ultimo ciclo - Vecchio SRTT |
La formula di livellamento viene quindi utilizzata per tenere conto dell'ultimo valore:
Nuovo SDEV = 3/4 × vecchio SDEV + 1/4 × DEV
Rimane una domanda: quali sono i valori iniziali? Consigliato:
Timeout iniziale = 3 s
SRTT iniziale = 0
SDEV iniziale = 1,5 s
Van Jacobson ha definito un algoritmo veloce che calcola il timeout di ritrasmissione in modo molto efficiente.
10.13.6 Statistiche di esempio
Quanto bene funzionerà il timeout calcolato sopra? Sono stati osservati miglioramenti significativi delle prestazioni quando il valore risultante è stato realizzato. Un esempio potrebbero essere le statistiche di squadra netstat ricevuto sul sistema tigro- un server Internet a cui accedono molti host da tutto il mondo.
1510769 pacchetti (314955304 byte) ricevuti in sequenza
Sistema tigro meno del 2,5% dei segmenti di dati TCP sono stati ritrasmessi. Per un milione e mezzo di segmenti di dati in entrata (il resto sono messaggi ACK puri), solo lo 0,6% è stato duplicato. Va tenuto presente che il livello di perdita nei dati di input corrisponde approssimativamente al livello per i segmenti di output. Pertanto, il traffico di ritrasmissione inutile costituisce circa lo 0,6% del traffico totale.
10.13.7 Calcoli dopo il reinvio
Le formule precedenti utilizzano il valore del tempo di ciclo come intervallo tra l'invio di un segmento e la ricezione di un riconoscimento. Tuttavia, supponiamo che non venga ricevuto alcun riconoscimento durante il periodo di timeout e che i dati debbano essere reinviati.
L'algoritmo di Kern presuppone che il tempo di ciclo non debba essere modificato in questo caso. L'attuale valore livellato del tempo di ciclo e deviazione livellata mantieni i loro valori fino a quando non viene ricevuto un riconoscimento per inviare un determinato segmento senza inviarlo nuovamente. A questo punto si riprendono i calcoli in base ai valori salvati e alle nuove misurazioni.
10.13.8 Azioni dopo la ritrasmissione
Ma cosa succede prima che venga ricevuta la conferma? Dopo la ritrasmissione, il comportamento di TCP cambia radicalmente, principalmente a causa della perdita di dati dovuta alla congestione della rete. Pertanto, la reazione al reinvio dei dati sarà:
■ Ridurre la velocità di rispedizione
■ Ridurre la congestione della rete riducendo il traffico complessivo
10.13.9 Frenatura esponenziale
Dopo la ritrasmissione, l'intervallo di timeout viene raddoppiato. Tuttavia, cosa succede se il timer trabocca di nuovo? I dati verranno nuovamente inviati e il periodo di ritrasmissione sarà nuovamente raddoppiato. Questo processo si chiama decelerazione esponenziale(backoff esponenziale).
Se l'interruzione di rete persiste, il periodo di timeout raddoppierà fino al raggiungimento del valore massimo preimpostato (tipicamente 1 minuto). È possibile inviare un solo segmento dopo il timeout. Il timeout si verifica anche quando viene superato il valore predeterminato per il numero di trasferimenti di dati senza ricevere un ACK.
13.10.10 Ridurre la congestione riducendo la quantità di dati inviati in rete
Ridurre la quantità di dati trasferiti è un po' più complesso dei meccanismi discussi sopra. Inizia a funzionare, come il già citato avvio lento. Tuttavia, poiché viene impostato un limite per il livello di traffico, che inizialmente può portare a problemi, il tasso di cambio rallenterà effettivamente a causa di un aumento delle dimensioni della finestra di carico per un segmento. Devi impostare i valori del bordo per ridurre davvero la velocità di caricamento. Innanzitutto, viene calcolata la soglia di pericolo:
Limite - 1/2 minimo (finestra di caricamento corrente, finestra di ricezione del partner)
Se il valore ottenuto è più di due segmenti, viene utilizzato come confine. In caso contrario, il bordo è impostato su due segmenti. Un algoritmo di ripristino completo richiede:
■ Impostare la dimensione della finestra di caricamento su un segmento.
S Per ogni ACK ricevuto, aumentare la finestra di caricamento di un segmento fino a raggiungere il limite (molto simile a un meccanismo di avvio lento).
■ Quindi, ad ogni ACK ricevuto, aggiungere un valore più piccolo alla finestra di caricamento, che viene selezionata in base alla velocità di aumento in un segmento per il tempo di ciclo (l'aumento è calcolato come MSS / N, dove N è la dimensione del finestra di caricamento in segmenti).
Uno scenario ideale potrebbe semplificare il lavoro del meccanismo di ripristino. Supponiamo che la finestra di ricezione del partner (e la finestra di caricamento corrente) fosse di 8 segmenti prima che fosse rilevato il timeout e che il confine fosse definito come 4 segmenti. Se l'applicazione ricevente legge istantaneamente i dati dal buffer, la finestra di ricezione rimane a 8 segmenti.
■ Viene inviato 1 segmento (finestra di caricamento = 1 segmento).
■ ACK ricevuto: vengono inviati 2 segmenti.
■ ACK per 2 segmenti ricevuti: vengono inviati 4 segmenti (limite raggiunto).
■ ACK ricevuto per 4 segmenti. Vengono inviati 5 segmenti.
■ ACK ricevuto per 5 segmenti. Vengono inviati 6 segmenti.
■ ACK ricevuto per 6 segmenti. Vengono inviati 7 segmenti.
■ ACK ricevuto per 7 segmenti. Vengono inviati 8 segmenti (la finestra di caricamento è ancora di dimensioni uguali alla finestra di ricezione).
Poiché durante il timeout di ritrasmissione è richiesto il riconoscimento di tutti i dati inviati, il processo continua finché la finestra di caricamento non raggiunge le dimensioni della finestra di ricezione. Gli eventi in atto sono mostrati in Fig. 10.20. La dimensione della finestra aumenta in modo esponenziale, raddoppiando durante il periodo di avvio lento, e quando raggiunge il limite, aumenta linearmente.
![](https://i1.wp.com/redov.ru/kompyutery_i_internet/tcp_ip_arhitektura_protokoly_realizacija_vklyuchaja_ip_versii_6_i_ip_security/img_142.png)
Riso. 10.20. Limitazione della velocità di trasferimento durante la congestione
13.10.11 ACK duplicati
In alcune implementazioni viene utilizzata una funzione opzionale, la cosiddetta rispedizione veloce(ritrasmissione veloce) - al fine di accelerare la ritrasmissione dei dati in determinate condizioni. La sua idea principale è legata all'invio di ACK aggiuntivi da parte del destinatario, indicando un vuoto nei dati ricevuti.
Alla ricezione di un segmento fuori ordine, il ricevitore restituisce un ACK che punta al primo byte. perduto dati (vedi Figura 10.21).
![](https://i1.wp.com/redov.ru/kompyutery_i_internet/tcp_ip_arhitektura_protokoly_realizacija_vklyuchaja_ip_versii_6_i_ip_security/img_143.png)
Riso. 21.10. ACK duplicati
Il mittente non ritrasmette istantaneamente i dati perché l'IP può normalmente consegnare i dati al destinatario senza una sequenza di invio. Ma quando vengono ricevuti diversi ACK aggiuntivi per i dati duplicati (ad esempio tre), il segmento mancante verrà inviato senza attendere la scadenza del timeout.
Nota che ogni ACK duplicato indica la ricezione di un segmento di dati. Diversi ACK duplicati consentono di sapere che la rete è in grado di fornire dati sufficienti e quindi non è sovraccaricata. Come parte dell'algoritmo complessivo, viene eseguita una piccola riduzione delle dimensioni della finestra di caricamento con un reale aumento del traffico di rete. In questo caso, il processo di ridimensionamento radicale durante il ripristino del lavoro non si applica.
Secondo lo standard Requisiti dell'host(requisiti dell'host) TCP dovrebbe eseguire lo stesso avvio lento descritto sopra durante l'estinzione della sorgente (estinzione della sorgente). Tuttavia, segnalare questo non è mirato o efficace perché la connessione che riceve questo messaggio potrebbe non generare troppo traffico. Specifiche attuali Requisiti del router(requisiti del router) indica che i router non dovrebbe inviare messaggi sulla soppressione della fonte.
10.13.13 Statistiche TCP
Infine, diamo uno sguardo ai messaggi statistici del comando netstat, vedere all'opera molti dei meccanismi sopra descritti.
I segmenti sono denominati pacchetti.879137 pacchetti di dati (226966295 byte)
21815 pacchetti di dati (8100927 byte) ritrasmessiRispedizione.
132957 pacchetti di sola conferma (104216 ritardati)Notiamo un gran numero
ACK ritardato.
Apertura della finestra di sondaggiodimensione zero.
Questi sono i messaggi SYN e FIN.762469 acks (per 226904227 byte)Avviso per i pacchi in arrivo
fuori sequenza.
1510769 pacchetti (314955304 byte)
9006 pacchetti completamente duplicati (867042 byte)Il risultato del timeout quando il real
consegna dei dati.
74 pacchetti con qualche duplicazione. dati (12193 byte duplicati)Per una maggiore efficienza
alcuni dati sono stati riconfezionati per includere byte aggiuntivi quando sono stati reinviati.
13452 pacchetti fuori ordine (2515087 byte)
530 pacchetti (8551 byte) di dati dopo la finestraForse questo dato era
inclusi nei messaggi di rilevamento.
402 pacchetti ricevuti dopo la chiusuraQueste sono repliche di follow-up
invio.
108 scartati per checksum erratiChecksum TCP non valido.
0 scartato per campi di offset dell'intestazione errati
7 scartato perché il pacchetto è troppo corto
14677 connessioni stabilite (compresi accetta)
18929 connessioni chiuse (incluse 643 drop)
4100 connessioni embrionali interrotte
572187 segmenti aggiornati rtt (di 587397 tentativi)Tentativi di modifica falliti
il tempo di ciclo, perché l'ACK non ha avuto il tempo di arrivare prima della scadenza del timeout,
26 connessioni interrotte da rexmit timeoutSuccessivi tentativi falliti
reinvio, che indica una connessione persa.
Timeout di sondaggiofinestra zero.
Timeout di pagamentoconnessione interrotta.
472 connessioni eliminate da keepalive
10.14 Conformità ai requisiti dello sviluppatore
L'attuale standard TCP richiede che le implementazioni aderiscano a una procedura di avvio lento durante l'inizializzazione di una connessione e utilizzino gli algoritmi Kern e Jacobson per stimare il timeout di ritrasmissione e gestire il carico. I test hanno dimostrato che questi meccanismi portano a significativi miglioramenti delle prestazioni.
Cosa succede se installi un sistema che non aderisce a questi standard? Non sarà in grado di fornire prestazioni adeguate ai propri utenti e sarà un cattivo vicino per altri sistemi sulla rete, impedendo il ripristino del normale funzionamento dopo una congestione temporanea e generando traffico eccessivo che si traduce in datagrammi persi.
10.15 Ostacoli alla performance
TCP ha dimostrato la sua flessibilità, operando su reti con tassi di cambio di centinaia o milioni di bit al secondo. Questo protocollo ha permesso di ottenere buoni risultati nelle moderne reti locali con topologie Ethernet, Token-Ring e Fiber Distributed Data Interface (FDDI), nonché per linee di comunicazione a bassa velocità o connessioni a lunga distanza (come i collegamenti satellitari) .
TCP è progettato per rispondere a condizioni estreme come la congestione della rete. Tuttavia, l'attuale versione del protocollo ha caratteristiche che limitano le prestazioni in tecnologie promettenti che offrono una larghezza di banda di centinaia e migliaia di megabyte. Per comprendere i problemi che sorgono, considera un esempio semplice (sebbene irrealistico).
Supponiamo che quando si sposta un file tra due sistemi, si desidera scambiare un flusso continuo nel modo più efficiente possibile. Supponiamo che:
■ La dimensione massima del segmento di destinazione è 1 KB.
■ Finestra di ricezione - 4 Kbyte.
■ La larghezza di banda consente di inviare due segmenti in 1 secondo.
■ L'applicazione ricevente consuma i dati non appena arrivano.
I messaggi S ACK arrivano in 2 secondi.
Il mittente è in grado di inviare dati in modo continuo. Dopotutto, quando il volume allocato per la finestra è pieno, arriva un ACK che consente l'invio di un altro segmento:
Dopo 2 secondi:
RICEVERE ACK DEL SEGMENTO 1, PU INVIARE SEGMENTO 5.
RICEVERE ACK DEL SEGMENTO 2, PU INVIARE SEGMENTO 6.
RICEVERE ACK DEL SEGMENTO 3, PU INVIARE IL SEGMENTO 7.
RICEVERE ACK DEL SEGMENTO 4, PU INVIARE SEGMENTO 8.
Dopo altri 2 s:
RICEVERE ACK DEL SEGMENTO 5, PU INVIARE SEGMENTO 9.
Se la finestra di ricezione fosse di soli 2 KB, il mittente dovrebbe attendere un secondo ogni due prima di inviare i dati successivi. Infatti, per mantenere un flusso continuo di dati, la finestra di ricezione deve essere almeno:
Finestra = Larghezza di banda × Tempo di ciclo
Sebbene l'esempio sia un po' esagerato (per fornire numeri più semplici), la finestra piccola può portare a problemi con le connessioni satellitari ad alta latenza.
Ora diamo un'occhiata a cosa succede alle connessioni ad alta velocità. Ad esempio, se la larghezza di banda e la velocità di trasferimento sono misurate a 10 milioni di bit al secondo, ma il tempo di ciclo è di 100 ms (1/10 di secondo), quindi per un flusso continuo, la finestra di ricezione deve memorizzare almeno 1.000.000 di bit, cioè... 125.000 byte. Ma il numero più grande che può essere scritto nel campo di intestazione per una finestra di ricezione TCP è 65.536.
Un altro problema si verifica a velocità di trasmissione elevate, poiché i numeri di sequenza si esauriscono molto rapidamente. Se la connessione può trasferire dati a una velocità di 4 GB / s, i numeri di sequenza dovrebbero essere aggiornati ogni secondo. Non sarà possibile distinguere tra vecchi datagrammi duplicati che sono stati ritardati di più di un secondo durante la navigazione in Internet da dati nuovi e freschi.
Sono in corso nuove ricerche per migliorare TCP/IP e rimuovere le barriere di cui sopra.
10.16 Funzioni TCP
Questo capitolo si concentra sulle molte caratteristiche del TCP. I principali sono elencati di seguito:
■ Associazione delle porte alle connessioni
■ Inizializzazione delle connessioni tramite conferma in 3 passaggi
■ Esegue un avvio lento per evitare la congestione della rete
■ Segmentazione dei dati in transito
■ Numerazione dei dati
■ Gestione di segmenti duplicati in entrata
■ Calcolo dei checksum
■ Regolazione del flusso di dati attraverso la finestra di ricezione e la finestra di invio
■ Interruzione della connessione nel modo stabilito
■ Terminare la connessione
■ Inoltro di dati urgenti
■ Conferma positiva della rispedizione
■ Calcolo del timeout di ritrasmissione
■ Traffico di ritorno ridotto durante la congestione della rete
■ Allarme per arrivo segmento fuori servizio
■ Percependo la chiusura della finestra di ricezione
10.17 Stati TCP
Una connessione TCP passa attraverso più fasi: la connessione viene stabilita tramite lo scambio di messaggi, quindi vengono inviati i dati, quindi la connessione viene chiusa utilizzando lo scambio di messaggi speciali. Ogni passo nel lavoro della connessione corrisponde a un certo condizione questa connessione. Il software TCP a ciascuna estremità della connessione monitora costantemente lo stato corrente dell'altro lato della connessione.
Di seguito esamineremo brevemente una tipica transizione di stato del server e del client situati alle diverse estremità della connessione. Non intendiamo fornire una descrizione esaustiva di tutti i possibili stati durante il trasferimento dei dati. Si trova in RFC 793 e in Requisiti dell'host.
Durante la creazione delle connessioni, il server e il client attraversano sequenze di stati simili. Gli stati del server sono mostrati nella Tabella 10.3 e gli stati del client sono mostrati nella Tabella 10.4.
Tabella 10.3 Sequenza dello stato del server
Stato del server | Evento | Descrizione |
---|---|---|
CHIUSO (chiuso) | Uno stato fittizio prima di iniziare una connessione. | |
Apertura passiva tramite applicazione server. | ||
ASCOLTA (inseguimento) | Il server è in attesa di una connessione client. | |
Il server TCP riceve un SYN e invia un SYN/ACK. | Il server ha ricevuto un SYN e ha inviato un SYN/ACK. Va in attesa di ACK. | |
SYN-RICEVUTO | Il server TCP riceve l'ACK. | |
STABILITO (installato) | ACK ricevuto, connessione aperta. |
Tabella 10.4 Sequenza dello stato del cliente
Se i partner tentassero simultaneamente di stabilire una connessione tra loro (cosa che accade molto raramente), ciascuno passerebbe attraverso gli stati CLOSED, SYN-SENT, SYN-RECEIVED e ESTABLISHED.
I lati finali della connessione rimangono nello stato ESTABLISHED fino a quando uno dei lati inizia chiusura connessioni inviando un segmento FIN. Durante una chiusura normale, la parte che avvia la chiusura attraversa gli stati mostrati nella Tabella 10.5. Il suo partner passa attraverso gli stati mostrati nella tabella 10.6.
Tabella 10.5 Sequenza di stato della parte che chiude la connessione
Chiusura degli stati secondari | Evento | Descrizione |
---|---|---|
STABILITO | L'applicazione locale richiede di chiudere la connessione. | |
TCP invia FIN / ACK. | ||
FIN-ATTENDERE-1 | La controparte è in attesa della risposta del partner. Ricordiamo che potrebbero ancora arrivare nuovi dati dal partner. | |
TCP riceve ACK. | ||
FIN-ATTENDERE-2 | Il lato di chiusura ha ricevuto un ACK dal partner, ma il FIN non è ancora arrivato. Il lato di chiusura attende un FIN, accettando i dati in arrivo. | |
TCP riceve FIN / ACK. | ||
Invia ACK. | ||
TEMPO DI ATTESA | La connessione viene mantenuta in uno stato indeterminato per consentire l'arrivo o l'interruzione di dati duplicati o FIN duplicati ancora esistenti sulla rete. Il periodo di attesa è il doppio della stima della durata massima del segmento. | |
CHIUSO |
Tabella 10.6 Sequenza degli stati partner per chiudere una connessione
Stato di partner | Evento | Descrizione |
---|---|---|
STABILITO | TCP riceve FIN / ACK. | |
CHIUDERE-ATTENDERE | FIN è arrivato. | |
TCP invia ACK. | ||
TCP attende che la sua applicazione chiuda la connessione. A questo punto, l'applicazione può inviare una quantità di dati abbastanza grande. | ||
L'applicazione locale avvia la chiusura della connessione. | ||
TCP invia FIN / ACK. | ||
LAST-ACK | TCP è in attesa dell'ACK finale. | |
TCP riceve ACK. | ||
CHIUSO | Rimosse tutte le informazioni di connessione. |
10.17.1 Analisi degli stati di connessione TCP
Squadra netstat -an consente di verificare lo stato attuale della connessione. Le connessioni negli stati sono mostrate di seguito ascolta, avvio, stabilito, chiusura e tempo di attesa.
Notare che il numero della porta di connessione è elencato alla fine di ogni indirizzo locale ed esterno. Puoi vedere che c'è traffico TCP sia per le code in entrata che per quelle in uscita.
Pro Recv-Q Send-Q Indirizzo locale Indirizzo estero (stato)
Tcp 0 0 128.121.50.145.25 128.252.223.5.1526 SYN_RCVD
Tcp 0 0 128.121.50.145.25 148.79.160.65.3368 COSTITUITO
Tcp 0 0 127.0.0.1.1339 127.0.0.1.111 TIME_WAIT
Tcp 0 438 128.121.50.145.23 130.132.57.246.2219 STABILITA
Tcp 0 0 128.121.50.145.25 192.5.5.1.4022 TIME_WAIT
Tcp 0 0 128.121.50.145.25 141.218.1.100.3968 TIME_WAIT
Tcp 0 848 128.121.50.145.23 192.67.236.10.1050 STABILITO
Tcp 0 0 128.121.50.145.1082 128.121.50.141.6000 STABILITO
Tcp 0 0 128.121.50.145.1022 128.121.50.141.1017 STABILITO
Tcp 0 0 128.121.50.145.514 128.121.50.141.1020 CLOSE_WAIT
Tcp 0 1152 128.121.50.145.119 192.67.239.23.3572 STABILITO
Tcp 0 0 128.121.50.145.1070 192.41.171.5.119 TIME_WAIT
Tcp 579 4096 128.121.50.145.119 204.143.19.30.1884 COSTITUITO
Tcp 0 0 128.121.50.145.119 192.67.243.13.3704 STABILITA
Tcp 0 53 128.121.50.145.119 192.67.236.218.2018 FIN_WAIT_1
Tcp 0 0 128.121.50.145.119 192.67.239.14.1545 COSTITUITO
10.18 Note di implementazione
Fin dall'inizio, TCP è stato progettato per far interagire apparecchiature di rete di diversi produttori. La specifica TCP non specifica esattamente come dovrebbero funzionare le strutture di implementazione interne. Queste domande sono lasciate agli sviluppatori per trovare i migliori meccanismi per ogni specifica implementazione.
Anche RFC 1122 (documento Requisiti dell'host - requisiti dell'host) lascia abbastanza spazio per le variazioni. Ciascuna delle funzioni implementate è contrassegnata da un certo livello di compatibilità:
■ MAGGIO (consentito)
■ NON DEVE
Sfortunatamente, a volte ci sono prodotti che non implementano i requisiti MUST. Di conseguenza, gli utenti sperimentano inconvenienti di degrado delle prestazioni.
Alcune buone pratiche di implementazione non sono considerate negli standard. Ad esempio, è possibile migliorare la sicurezza limitando l'uso di porte note da parte dei processi di sistema privilegiati se questo metodo è supportato nel sistema operativo locale. Per massimizzare le prestazioni, le implementazioni dovrebbero avere il minor numero possibile di operazioni di copia e spostamento dei dati inviati o recuperati.
API standard indefinito(così come la politica di sicurezza) in modo che ci sia un campo di attività libero per sperimentare diversi set di strumenti software. Tuttavia, ciò potrebbe comportare l'utilizzo di API diverse su ciascuna piattaforma e impedirà lo spostamento del software applicativo tra le piattaforme.
In effetti, gli sviluppatori basano i loro toolkit sull'API Socket di Berkeley. L'importanza dell'interfaccia di programmazione è aumentata con l'avvento di WINSock (Windows Socket), che ha portato a una proliferazione di nuove applicazioni desktop che potrebbero essere eseguite su qualsiasi interfaccia WINSock compatibile con lo stack TCP/IP.
10.19 Ulteriori letture
Lo standard TCP originale è definito nella RFC 793. Aggiornamenti, correzioni e requisiti di interoperabilità sono trattati nella RFC 1122. Kern (Kash) e Partridge (Partridge) hanno pubblicato un articolo Miglioramento delle stime di andata e ritorno in protocolli di trasporto affidabili Nella rivista Atti dell'ACM SIGCOMM 1987. L'articolo di Jacobson Prevenzione e controllo della congestione apparso in Atti del Workshop ACM SIGCOMM 1988. Jacobson ha anche emesso diverse RFC per la revisione degli algoritmi di miglioramento delle prestazioni.
I server che implementano questi protocolli sulla rete aziendale forniscono al client un indirizzo IP, un gateway, una maschera di rete, server dei nomi e persino una stampante. Gli utenti non devono configurare manualmente i propri host per utilizzare la rete.
Il sistema operativo QNX Neutrino implementa un altro protocollo plug-and-play chiamato AutoIP, che è un progetto del comitato di configurazione automatica IETF. Questo protocollo viene utilizzato su piccole reti per assegnare indirizzi IP a host che sono link-local. Il protocollo AutoIP determina in modo indipendente l'indirizzo IP locale del canale, utilizzando uno schema di negoziazione con altri host e senza contattare un server centrale.
Utilizzo del protocollo PPPoE
PPPoE è l'acronimo di Point-to-Point Protocol over Ethernet. Questo protocollo incapsula i dati per la trasmissione su una rete Ethernet con bridge.
PPPoE è una specifica per connettere utenti Ethernet a Internet tramite una connessione a banda larga, come una linea dedicata, un dispositivo wireless o un modem via cavo. L'uso di PPPoE e di un modem a banda larga fornisce agli utenti della rete informatica locale un accesso autenticato individuale alle reti di dati ad alta velocità.
PPPoE combina Ethernet con PPP per creare in modo efficiente una connessione separata a un server remoto per ogni utente. Il controllo dell'accesso, l'accounting della connessione e la selezione del provider di servizi sono specifici dell'utente, non dell'host. Il vantaggio di questo approccio è che né la compagnia telefonica né il provider di servizi Internet sono tenuti a fornire alcun supporto speciale per questo.
A differenza delle connessioni dial-up, le connessioni DSL e via cavo sono sempre attive. Poiché la connessione fisica a un provider di servizi remoto è condivisa da più utenti, è necessario un metodo di contabilità che registri i mittenti e le destinazioni del traffico e addebiti gli utenti. PPPoE consente a un utente e a un host remoto che partecipano a una comunicazione di apprendere gli indirizzi di rete dell'altro durante uno scambio iniziale chiamato rilevamento(scoperta). Una volta stabilita una sessione tra un singolo utente e un sito remoto (come un provider di servizi Internet), la sessione può essere monitorata per ratei. In molte case, hotel e aziende, l'accesso a Internet è condiviso su linee di abbonati digitali utilizzando la tecnologia Ethernet e PPPoE.
Una connessione PPPoE è costituita da un client e un server. Il client e il server funzionano utilizzando qualsiasi interfaccia vicina alle specifiche Ethernet. Questa interfaccia viene utilizzata per inviare indirizzi IP ai client, associando tali indirizzi IP agli utenti e, facoltativamente, alle workstation, invece dell'autenticazione della sola workstation. Il server PPPoE crea una connessione punto-punto per ogni client.
Stabilire una sessione PPPoE
Per creare una sessione PPPoE, dovresti usare il serviziopppoed... Moduloio-pkt- * nFornisce servizi di protocollo PPPoE. Per prima cosa devi correreio-pkt- *Conautista adatto... Esempio:
Viaggiare su protocolli di rete.
TCP e UDP sono entrambi protocolli di livello di trasporto. UDP è un protocollo senza connessione con consegna di pacchetti non protetta. TCP (Transmission Control Protocol) è un protocollo orientato alla connessione con consegna dei pacchetti garantita. Prima c'è una stretta di mano (Ciao. | Ciao. | Parliamo? | Dai.), Dopo di che la connessione è considerata stabilita. Inoltre, i pacchetti vengono inviati avanti e indietro su questa connessione (c'è una conversazione) e con un controllo se il pacchetto ha raggiunto il destinatario. Se il pacchetto viene perso, o è arrivato, ma con un po' di checksum, viene inviato di nuovo ("ripetere, non ho sentito"). Quindi, TCP è più affidabile, ma è più difficile dal punto di vista dell'implementazione e, di conseguenza, richiede più clock / memoria, il che non è il meno importante per i microcontrollori. Esempi di protocolli applicativi che utilizzano TCP includono FTP, HTTP, SMTP e molti altri.
TL; DR
HTTP (Hypertext Transfer Protocol) è un protocollo applicativo attraverso il quale il server invia pagine al nostro browser. HTTP è ormai onnipresente nel World Wide Web per recuperare informazioni dai siti web. L'immagine mostra una luce su un microcontrollore con un sistema operativo a bordo, in cui i colori vengono impostati tramite il browser.
Il protocollo HTTP è testuale e abbastanza semplice. In realtà, ecco come appare il metodo GET, inviato dall'utility netcat all'indirizzo IPv6 locale del server con luci:
~ $ nc fe80 :: 200: e2ff: fe58: b66b% mazko 80< Il metodo HTTP è solitamente una breve parola inglese in maiuscolo, con distinzione tra maiuscole e minuscole. Ogni server deve supportare almeno i metodi GET e HEAD. Oltre ai metodi GET e HEAD, vengono spesso utilizzati i metodi POST, PUT e DELETE. Il metodo GET serve per richiedere il contenuto della risorsa specificata, nel nostro caso qui GET/b HTTP/1.0 dove il percorso/b è responsabile del colore (blu). Risposta del server: HTTP / 1.0 200 OK Server: Contiki / 2.4 http://www.sics.se/contiki/ Connessione: close Cache-Control: no-cache, no-store, must-revalidate Pragma: no-cache Scade: 0 Contenuto- digita: testo / html Il rosso è spento Il verde è spento Il blu è acceso
Il codice di stato (abbiamo 200) fa parte della prima riga della risposta del server. È un numero intero di tre cifre. La prima cifra indica la classe della condizione. Il codice di risposta è solitamente seguito da una frase esplicativa in inglese, separata da uno spazio, che spiega alla persona il motivo di questa particolare risposta. Nel nostro caso, il server ha funzionato senza errori, tutto insieme (OK).
Sia la richiesta che la risposta contengono intestazioni (ogni riga è un campo di intestazione separato, la coppia nome-valore è separata da due punti). Le intestazioni terminano con una riga vuota, dopodiché i dati possono essere inseriti.
Il mio browser si rifiuta di aprire l'indirizzo IPv6 locale, quindi un indirizzo aggiuntivo viene scritto nel firmware del microcontrollore e lo stesso prefisso deve essere assegnato anche all'interfaccia di rete virtuale del simulatore:
~ $ sudo ip addr add abcd :: 1/64 dev mazko # linux ~ $ netsh interface ipv6 set address mazko abcd :: 1 # windows ~ $ curl http: //
Applicazione client-server su socket di streaming TCP
Nell'esempio seguente, utilizziamo TCP per fornire flussi di byte ordinati e affidabili a due vie. Costruiamo un'applicazione completa che includa un client e un server. Dimostriamo prima come costruire un server su socket di streaming TCP, quindi un'applicazione client per testare il nostro server.
Il seguente programma crea un server che riceve le richieste di connessione dai client. Il server è costruito in modo sincrono, quindi l'esecuzione del thread è bloccata fino a quando il server non accetta di connettersi al client. Questa app mostra un semplice server che risponde a un client. Il client termina la connessione inviando un messaggio al server
Server TCP
La creazione della struttura del server è mostrata nel seguente diagramma funzionale:
Ecco il codice completo per il programma SocketServer.cs:
// SocketServer.cs che utilizza System; utilizzando System.Text; utilizzando System.Net; utilizzando System.Net.Sockets; namespace SocketServer (class Program (static void Main (string args) (// Imposta l'endpoint locale per il socket IPHostEntry ipHost = Dns.GetHostEntry ("localhost"); IPAddress ipAddr = ipHost.AddressList; IPEndPoint ipEndPoint = new IPEndPoint (ipAddr, 11 ); // Crea un socket Tcp / Ip sListener = new Socket (ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp); // Assegna il socket all'endpoint locale e ascolta i socket in entrata try (sListener.Bind (ipEndPoint ); sListener. Listen (10); // Avvia l'ascolto delle connessioni while (true) (Console.WriteLine ("In attesa di una connessione sulla porta (0)", ipEndPoint); // Il programma si interrompe, in attesa di una connessione in entrata Socket handler = sListener.Accept (); string data = null; // Abbiamo aspettato che un client tentasse di connettersi con noi byte bytes = new byte; int bytesRec = handler.Receive (byte); data + = Encoding.UTF8.GetString (bytes, 0, bytesRec); // Mostra i dati sulla console Console.Write ("Received testo: "+ dati +" \ n \ n "); // Invia una risposta al client \ string reply = "Grazie per la richiesta in" + data.Length.ToString() + "characters"; byte msg = Encoding.UTF8.GetBytes (risposta); gestore.Invia (msg); if (data.IndexOf ("
Diamo un'occhiata alla struttura di questo programma.
Il primo passaggio consiste nello stabilire un endpoint locale per il socket. Prima di aprire un socket per ascoltare le connessioni, è necessario preparare un indirizzo di endpoint locale per esso. L'indirizzo univoco per il servizio TCP/IP è determinato dalla combinazione dell'indirizzo IP dell'host con il numero di porta del servizio che crea l'endpoint per il servizio.
La classe Dns fornisce metodi che restituiscono informazioni sugli indirizzi di rete supportati da un dispositivo su una rete locale. Se un dispositivo LAN ha più di un indirizzo di rete, la classe Dns restituisce informazioni su tutti gli indirizzi di rete e l'applicazione deve selezionare un indirizzo adatto dall'array da servire.
Crea un IPEndPoint per il server combinando il primo indirizzo IP host dal metodo Dns.Resolve() con il numero di porta:
IPHostEntry ipHost = Dns.GetHostEntry ("localhost"); IPAddress ipAddr = ipHost.AddressList; IPEndPoint ipEndPoint = nuovo IPEndPoint (ipAddr, 11000);
Qui la classe IPEndPoint rappresenta localhost sulla porta 11000. Quindi, creare un socket di flusso con una nuova istanza della classe Socket. Con un endpoint locale configurato per ascoltare le connessioni, è possibile creare un socket:
Socket sListener = nuovo Socket (ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
Enumerazione IndirizzoFamiglia specifica gli schemi di indirizzamento che un'istanza della classe Socket può utilizzare per risolvere un indirizzo.
Nel parametro Tipo di presa ci sono socket TCP e UDP. In esso è possibile definire, tra l'altro, i seguenti valori:
DgramSupporta datagrammi. Il valore Dgram richiede di specificare Udp per il tipo di protocollo e InterNetwork nel parametro della famiglia di indirizzi.
CrudoSupporta l'accesso al protocollo di trasporto sottostante.
FlussoSupporta i socket di streaming. Il valore Stream richiede che sia specificato Tcp per il tipo di protocollo.
Il terzo e ultimo parametro definisce il tipo di protocollo richiesto per il socket. Nel parametro Tipo di protocollo puoi specificare i seguenti valori più importanti: Tcp, Udp, Ip, Raw.
Il prossimo passo dovrebbe essere quello di assegnare il socket usando il metodo Legamento ()... Quando un socket viene aperto dal costruttore, non gli viene assegnato alcun nome, viene riservato solo un descrittore. Il metodo Bind() viene chiamato per assegnare un nome al socket del server. Affinché il socket client sia in grado di identificare il socket di streaming TCP, il programma server deve denominare il suo socket:
SListener.Bind (ipEndPoint);
Il metodo Bind() associa il socket all'endpoint locale. È necessario chiamare il metodo Bind() prima di qualsiasi tentativo di chiamare i metodi Listen() e Accept().
Ora, dopo aver creato un socket e associato ad esso un nome, puoi ascoltare i messaggi in arrivo utilizzando il metodo Ascolta ()... In uno stato di ascolto, il socket attende i tentativi di connessione in entrata:
Ascoltare.Ascolta (10);
Il parametro definisce arretrato che specifica il numero massimo di connessioni in sospeso nella coda. Nel codice indicato, il valore del parametro consente di accumulare fino a dieci connessioni nella coda.
Nello stato di ascolto bisogna essere pronti ad acconsentire alla connessione con il cliente, per il quale si utilizza il metodo Accetta ()... Questo metodo ottiene una connessione client e completa i collegamenti del nome client/server. Il metodo Accept() blocca il thread del chiamante finché non arriva una connessione.
Il metodo Accept() recupera la prima richiesta di connessione dalla coda delle richieste in sospeso e crea un nuovo socket per gestirla. Anche se viene creato il nuovo socket, il socket originale continua ad essere in ascolto e può essere multithread per ricevere più richieste di connessione dai client. Nessuna applicazione server dovrebbe chiudere il socket di ascolto. Dovrebbe continuare a funzionare insieme ai socket creati dal metodo Accept per gestire le richieste client in ingresso.
While (true) (Console.WriteLine ("In attesa di una connessione sulla porta (0)", ipEndPoint); // Il programma si interrompe, in attesa di una connessione in entrata Socket handler = sListener.Accept ();
Una volta che il client e il server hanno stabilito una connessione tra loro, puoi inviare e ricevere messaggi utilizzando i metodi Spedire () e Ricevere () Classe presa.
Il metodo Send() scrive i dati in uscita nel socket a cui è stabilita la connessione. Il metodo Receive() legge i dati in ingresso su un socket di flusso. Su un sistema basato su TCP, è necessario stabilire una connessione tra i socket prima di eseguire i metodi Send() e Receive(). Il protocollo esatto tra le due entità interagenti deve essere determinato in anticipo in modo che le applicazioni client e server non si blocchino a vicenda, non sapendo chi dovrebbe inviare per primo i propri dati.
Quando lo scambio di dati tra il server e il client è completato, è necessario chiudere la connessione utilizzando i metodi Spegnimento () e Vicino ():
Handler.Shutdown (SocketShutdown.Both); gestore.Chiudi ();
SocketShutdown è un'enumerazione contenente tre valori da interrompere: Entrambi- interrompe l'invio e la ricezione di dati dal socket, Ricevere- interrompe la ricezione dei dati sul socket e Spedire- interrompe l'invio di dati dal socket.
Il socket viene chiuso quando viene chiamato il metodo Close(), che imposta anche la proprietà Connected del socket su false.
Client su TCP
Le funzioni utilizzate per creare un'applicazione client assomigliano più o meno a un'applicazione server. Come con il server, vengono utilizzati gli stessi metodi per determinare l'endpoint, creare un'istanza del socket, inviare e ricevere dati e chiudere il socket.