Dimensioni dei pacchetti in un flusso TCP


10

Sono traffico di rete e desidero dividere ogni sessione TCP in una serie di richieste e risposte (i protocolli con cui sto lavorando funzionano in questo modo, come HTTP o SSL).

Ho avuto un semplice presupposto (ignorando i pacchetti fuori servizio e rinviati) - dato un mucchio di dati che devono essere inviati, saranno inviati usando i pacchetti più grandi possibili e l'ultimo pacchetto sarà più piccolo della dimensione massima o sarà seguito da un pacchetto dall'altra parte (ignorando i pacchetti vuoti ACK). Quindi in una sessione HTTP mi aspetto di vedere qualcosa di simile (di nuovo, ignorando acks) -

Pacchetto 1 - Richiesta "Ottieni ..."

Pacchetto 2 - Risposta, dimensione 1434

Pacchetto 3 - Risposta, dimensione 1434

Pacchetto 4 - Risposta, dimensione 1434

Pacchetto 5 - Risposta, dimensione 500

Il che è ciò che ottengo nella maggior parte delle sessioni, tuttavia c'è almeno un'occasione che ho visto che sembrava

Pacchetto 1 - Richiesta "Ottieni ..."

Pacchetto 2 - Risposta, dimensione 1434

Pacchetto 3 - Risposta, dimensione 1080

Pacchetto 4 - Risposta, dimensione 1434

Pacchetto 5 - Risposta, dimensione 500

Nessuna ritrasmissione, pacchetti fuori servizio qui o nessun ritardo eccezionale sul server.

Voglio sapere: cosa può causare questo e quando accadrà? Quanto è sbagliato il mio presupposto?

AGGIORNARE

Ho messo un esempio di file pcap qui

AGGIORNAMENTO 2

Inclusa una tsharkdiscarica con campi pertinenti ...

$ tshark -r http_1082.pcap -T fields -e frame.number -e frame.len \
    -e ip.src -e ip.dst -e tcp.flags.push -e http.request.method \
    -e http.request.uri -e http.response.code | head -n 47
1     66      192.168.1.103    206.33.49.126    0            
2     62      206.33.49.126    192.168.1.103    0            
3     64      192.168.1.103    206.33.49.126    0            
4     411     192.168.1.103    206.33.49.126    1    GET    /money/.element/script/3.0/video/xmp/xmp_playlistapi.js    
5     54      206.33.49.126    192.168.1.103    0            
6     1434    206.33.49.126    192.168.1.103    0            
7     1434    206.33.49.126    192.168.1.103    0            
8     64      192.168.1.103    206.33.49.126    0            
9     1434    206.33.49.126    192.168.1.103    0            
10    1434    206.33.49.126    192.168.1.103    0            
11    1434    206.33.49.126    192.168.1.103    0            
12    64      192.168.1.103    206.33.49.126    0            
13    1434    206.33.49.126    192.168.1.103    0            
14    1434    206.33.49.126    192.168.1.103    0            
15    1434    206.33.49.126    192.168.1.103    0            
16    1434    206.33.49.126    192.168.1.103    0            
17    64      192.168.1.103    206.33.49.126    0            
18    1434    206.33.49.126    192.168.1.103    0            
19    1434    206.33.49.126    192.168.1.103    0            
20    1434    206.33.49.126    192.168.1.103    0            
21    1434    206.33.49.126    192.168.1.103    0            
22    1434    206.33.49.126    192.168.1.103    0            
23    64      192.168.1.103    206.33.49.126    0            
24    1434    206.33.49.126    192.168.1.103    0            
25    1434    206.33.49.126    192.168.1.103    0            
26    1434    206.33.49.126    192.168.1.103    0            
27    1434    206.33.49.126    192.168.1.103    0            
28    1434    206.33.49.126    192.168.1.103    0            
29    1434    206.33.49.126    192.168.1.103    0            
30    64      192.168.1.103    206.33.49.126    0            
31    1434    206.33.49.126    192.168.1.103    0            
32    1434    206.33.49.126    192.168.1.103    0            
33    1434    206.33.49.126    192.168.1.103    0            
34    1082    206.33.49.126    192.168.1.103    1     <------ Packet in question        
35    1434    206.33.49.126    192.168.1.103    0            
36    1434    206.33.49.126    192.168.1.103    0            
37    1434    206.33.49.126    192.168.1.103    0            
38    64      192.168.1.103    206.33.49.126    0            
39    1434    206.33.49.126    192.168.1.103    0            
40    1434    206.33.49.126    192.168.1.103    0            
41    1434    206.33.49.126    192.168.1.103    0            
42    1434    206.33.49.126    192.168.1.103    0            
43    1434    206.33.49.126    192.168.1.103    0            
44    1434    206.33.49.126    192.168.1.103    0            
45    1434    206.33.49.126    192.168.1.103    0            
46    626     206.33.49.126    192.168.1.103    1            200
47    64      192.168.1.103    206.33.49.126    0 

Ci possono essere molti motivi ... La dimensione della finestra potrebbe essere troppo piccola (anche se molto improbabile nel tuo caso), potrebbero non esserci abbastanza dati da inviare (l'output è generato da uno script?), Il software che genera i dati potrebbe lo hanno scaricato esplicitamente, ecc.
Sander Steffann,

@SanderSteffann, le dimensioni della finestra non sembrano rilevanti, acks arrivano a intervalli abbastanza regolari. L'intera risposta è un javascript, quindi non penso che sia generato da un altro script.
Vadim,

@vadim, potresti per favore pubblicare uno screenshot o meglio, un collegamento ipertestuale al pcap con payload a 1080 byte?
Mike Pennington,

@MikePennington - grazie per il tuo contributo, ti fornirò un link al file pcap tra diverse ore.
Vadim,

@MikePennington - Ho aggiunto un collegamento a un file pcap che lo dimostra.
Vadim,

Risposte:


6

Il livello TCP utilizza l'algoritmo Nagle per bufferizzare il traffico (invia meno pacchetti di grandi dimensioni, anziché più piccoli pacchetti ... rendendolo più efficace); c'è un modo per l'applicazione di dire 'invialo ora'. Lo vedi nell'intestazione TCP con un flag chiamato bit PSH (push). Mentre il bit è impostato dallo stack, il push viene eseguito su richiesta dell'applicazione.

Quindi questo è un comportamento previsto e normale.



Esatto, c'era SUPPOSTO da fare nella RFC originale e ciò che era stato fatto Winsock e Socket
Fredpbaker,

dopo aver visto il pcap, è molto improbabile che il server web abbia impostato PSH sul traffico dell'OP
Mike Pennington,

3

La dimensione del pacchetto dipende dal modo in cui l'applicazione e / o il sistema operativo buffer e invia i dati di rete. Se l'applicazione e / o il sistema operativo decidono di inviare i dati dopo che nel buffer sono presenti 1080 byte, il pacchetto sarà di 1080 byte (più le intestazioni). Potrebbero esserci molte ragioni per farlo. Nel tuo caso dovresti cercare nel codice sorgente del server web e / o nello stack di rete del sistema operativo.


Vedo molti pacchetti con dimensioni massime e solo questo con dimensioni inferiori, quindi non è un valore predefinito di alcun tipo. Potrebbe essere stato un singhiozzo del server - è stato bloccato su qualcos'altro per un ritardo che è stato sufficiente per lo stack di rete per decidere di inviare ciò che era nel buffer?
Vadim,

Certo, avrebbe potuto essere qualsiasi cosa. Non è possibile dirlo senza eseguire il debug del server e del sistema operativo su cui è in esecuzione. Ma non c'è nulla di cui allarmarsi per l'IMHO.
Sebastian Wiesinger,

Non sono allarmato, mi è sembrato strano e volevo scoprire se c'è di più.
Vadim,

1
Se hai WireShark, cerca nell'intestazione TCP 1080 pacchetti il ​​bit PSH (push). Questo è lo stack dell'applicazione che dice invia ora questi dati.
Fredpbaker,

1
Vedi sopra, è lo stack TCP nella maggior parte dei casi
fredpbaker

1

La dimensione del pacchetto è definita dal sistema operativo (in generale) ed è correlata ai buffer, alla quantità di dati forniti dall'applicazione, ecc. Molte strategie possono essere utilizzate per ottenere le massime prestazioni e talvolta l'invio di pacchetti più piccoli può essere più veloce dell'attesa di creazione un pacchetto più grande.

A volte la quantità di app in esecuzione può richiedere che il sistema operativo sia più veloce (invia tutto ciò che ha nel buffer finora) invece di saturare il buffer.

Forse, potresti darci maggiori dettagli sullo scenario con cui stavi lavorando (es .: sistema operativo del server, app in esecuzione su di esso).


0

Fondamentalmente il problema è che l'implementazione TCP non sa cosa farà l'applicazione dopo. Quando l'applicazione server esegue una sequenza di scritture, lo stack non sa se le scritture ricevute finora sono l'intera sequenza o solo una parte di essa.

Il più delle volte l'applicazione server rende le scritture sul buffer più veloci di quanto lo stack di rete sia in grado di svuotarlo. Quindi il buffer è pieno ed escono pacchetti di dimensioni standard.

Ma a volte qualcos'altro rallenta l'applicazione del server. Forse in attesa di un disco letto su un array di dischi sovraccarico o qualcosa del genere. Quindi il buffer si svuota e lo stack di rete deve scegliere tra l'invio di un pacchetto più piccolo (più overhead) o l'attesa di dati che potrebbero non arrivare (aggiunta di ritardo).


0

Se guardi al frame 34, vedrai che il server ha trasmesso un buffer da 32kB e che il bit PSH è impostato. Se guardi 82 vedrai lo stesso, 32 kB dal precedente bit PSH. Il pacchetto 52 ha un bit PSH anche se ci sono stati meno di 2kB della risposta.

Il bit PSH è in genere impostato da uno stack TCP per l'ultimo segmento di una PDU dell'applicazione scritta sulla rete. Quindi l'applicazione utilizza un buffer da 32kB e quando ci sono molti dati, li scrive nel socket TCP da 32kB alla volta. Quando ci sono meno dati come nei frame 51-52, è perché l'applicazione ha scritto quel record per primo nella risposta ed era solo 1820 byte.

Si noti che l'applicazione a cui mi riferisco potrebbe in realtà non essere l'applicazione server stessa, ma alcuni software intermedi come una Java Virtual Machine (JVM) o altro. Non è chiaro dal contenuto dei dati perché è stata inviata quella PDU a 1820 byte, forse un buffer da 32kB non era disponibile al momento?

Il punto è che non dovrebbe importare, non c'è una sostanziale penalità di prestazione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.