Paketgrößen in einem TCP-Stream


10

Ich bin im Netzwerkverkehr und möchte jede TCP-Sitzung in eine Reihe von Anforderungen und Antworten aufteilen (die Protokolle, mit denen ich arbeite, funktionieren auf diese Weise, z. B. HTTP oder SSL).

Ich hatte eine einfache Annahme (Ignorieren von nicht in der richtigen Reihenfolge befindlichen und erneut gesendeten Paketen): Angesichts eines Datenblocks, der gesendet werden muss, werden die größtmöglichen Pakete gesendet, und das letzte Paket ist entweder kleiner als die maximale Größe oder wird befolgt durch ein Paket von der anderen Seite (ignoriert ACK leere Pakete). In einer HTTP-Sitzung erwarte ich also etwas wie (wieder ohne Rücksicht auf Bestätigungen) -

Paket 1 - Anfrage "Get ..."

Paket 2 - Antwort, Größe 1434

Paket 3 - Antwort, Größe 1434

Paket 4 - Antwort, Größe 1434

Paket 5 - Antwort, Größe 500

Welches ist, was ich auf den meisten Sitzungen bekomme, aber es gibt mindestens eine Gelegenheit, die ich sah, die aussah

Paket 1 - Anfrage "Get ..."

Paket 2 - Antwort, Größe 1434

Paket 3 - Antwort, Größe 1080

Paket 4 - Antwort, Größe 1434

Paket 5 - Antwort, Größe 500

Keine erneuten Übertragungen, nicht ordnungsgemäße Pakete oder keine außergewöhnlichen Verzögerungen auf dem Server.

Ich möchte wissen - was kann das verursachen und wann wird es auftreten? Wie falsch ist meine Annahme?

AKTUALISIEREN

Ich habe ein Beispiel pcap - Datei hier

UPDATE 2

Einschließlich eines tsharkDumps mit relevanten Feldern ...

$ 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 

Es kann so viele Gründe geben ... Die Fenstergröße ist möglicherweise zu klein (obwohl dies in Ihrem Fall sehr unwahrscheinlich ist), es sind möglicherweise nicht genügend Daten zum Senden vorhanden (wird die Ausgabe von einem Skript generiert?), Die Software generiert möglicherweise die Daten habe es explizit gespült usw.
Sander Steffann

@SanderSteffann, Fenstergröße scheint nicht relevant zu sein, Acks kommen in ziemlich regelmäßigen Abständen. Die gesamte Antwort ist ein Javascript, daher glaube ich nicht, dass es von einem anderen Skript generiert wird.
Vadim

@vadim, könntest du bitte einen Screenshot oder besser einen Hyperlink zum PCAP mit der 1080-Byte-Nutzlast posten?
Mike Pennington

@ MikePennington - danke für deine Eingabe, ich werde in einigen Stunden einen Link zur pcap-Datei bereitstellen.
Vadim

@ MikePennington - Ich habe einen Link zu einer PCAP-Datei hinzugefügt, der dies demonstriert.
Vadim

Antworten:


6

Die TCP-Schicht verwendet den Nagle-Algorithmus, um den Datenverkehr zu puffern (sie sendet weniger große Pakete anstelle von mehr kleinen Paketen ... was ihn effizienter macht). Es gibt eine Möglichkeit für die Anwendung, "Jetzt senden" zu sagen. Sie sehen das im TCP-Header mit einem Flag namens PSH (Push) -Bit. Während das Bit vom Stapel gesetzt wird, erfolgt der Push auf Anforderung der Anwendung.

Das ist also beabsichtigtes und normales Verhalten.



Ganz richtig, es gab das, was im ursprünglichen RFC gemacht werden sollte und was Winsock und Sockets gemacht wurden
Fredpbaker

Nach dem Betrachten der PCAP ist es sehr unwahrscheinlich, dass der Webserver PSH auf den OP-Verkehr eingestellt hat
Mike Pennington

3

Die Paketgröße hängt davon ab, wie die Anwendung und / oder das Betriebssystem Netzwerkdaten puffern und senden. Wenn die Anwendung und / oder das Betriebssystem beschließen, die Daten zu senden, nachdem sich 1080 Bytes im Puffer befinden, beträgt das Paket 1080 Bytes (plus Header). Dafür kann es viele Gründe geben. In Ihrem Fall müssten Sie im Webserver-Quellcode und / oder im OS-Netzwerkstapel nachsehen.


Ich sehe viele Pakete mit maximaler Größe und nur dieses mit einer kleineren Größe, es ist also keine Standardeinstellung. Könnte es ein Server-Schluckauf gewesen sein - es blieb für eine Verzögerung an etwas anderem hängen, die ausreichte, damit der Netzwerkstapel entscheiden konnte, was sich im Puffer befand?
Vadim

Klar, hätte alles sein können. Es gibt keine Möglichkeit, dies zu erkennen, ohne den Server und das Betriebssystem zu debuggen, auf dem er ausgeführt wird. Aber IMHO ist nichts zu beunruhigen.
Sebastian Wiesinger

Ich bin nicht beunruhigt, es schien nur seltsam und ich wollte herausfinden, ob mehr dahinter steckt.
Vadim

1
Wenn Sie Wireshark haben, suchen Sie im TCP-Header für 1080-Pakete nach dem PSH-Bit (Push-Bit). Das ist der Anwendungsstapel, der besagt, dass diese Daten jetzt gesendet werden.
Fredpbaker

1
Siehe oben, es ist in den meisten Fällen der TCP-Stack
Fredpbaker

1

Die Paketgröße wird vom Betriebssystem (im Allgemeinen) definiert und hängt mit den Puffern, der von der Anwendung bereitgestellten Datenmenge usw. zusammen. Viele Strategien können verwendet werden, um maximale Leistung zu erzielen, und manchmal kann das Senden kleinerer Pakete schneller sein als das Warten auf die Erstellung ein größeres Paket.

Manchmal kann die Anzahl der ausgeführten Apps erfordern, dass das Betriebssystem schneller ist (senden Sie alles, was sich bisher im Puffer befindet), anstatt den Puffer zu sättigen.

Vielleicht können Sie uns mehr Details zu dem Szenario geben, mit dem Sie gearbeitet haben (z. B. Server-Betriebssystem, darauf ausgeführte Apps).


0

Grundsätzlich besteht das Problem darin, dass die TCP-Implementierung nicht weiß, was die Anwendung als Nächstes tun wird. Wenn die Serveranwendung eine Schreibsequenz ausführt, weiß der Stapel nicht, ob die bisher empfangenen Schreibvorgänge die gesamte Sequenz oder nur einen Teil davon sind.

Meistens schreibt die Serveranwendung schneller in den Puffer, als der Netzwerkstapel ihn leeren kann. Der Puffer ist also voll und es werden Pakete in voller Größe ausgegeben.

Aber manchmal verlangsamt etwas anderes die Serveranwendung. Warten Sie möglicherweise auf eine Festplatte, die auf einem überlasteten Festplattenarray gelesen wurde, oder so. Der Puffer leert sich also und der Netzwerkstapel muss wählen, ob ein kleineres Paket gesendet werden soll (mehr Overhead) oder auf Daten warten soll, die möglicherweise nie kommen (zusätzliche Verzögerung).


0

Wenn Sie sich Frame 34 ansehen, werden Sie sehen, dass der Server einen 32-KB-Puffer übertragen hat und dass das PSH-Bit gesetzt ist. Wenn Sie sich 82 ansehen, sehen Sie dasselbe, 32 kB vom vorherigen PSH-Bit. Paket 52 hat ein PSH-Bit, obwohl weniger als 2 KB der Antwort vorhanden waren.

Das PSH-Bit wird normalerweise von einem TCP-Stapel für das letzte Segment einer in das Netzwerk geschriebenen Anwendungs-PDU gesetzt. Die Anwendung verwendet also einen 32-KB-Puffer und schreibt diese, wenn viele Daten vorhanden sind, jeweils 32 KB in den TCP-Socket. Wenn weniger Daten wie in den Frames 51-52 vorhanden sind, hat die Anwendung diesen Datensatz zuerst in der Antwort ausgeschrieben und es waren nur 1820 Byte.

Beachten Sie, dass die Anwendung, auf die ich mich beziehe, möglicherweise nicht die Serveranwendung selbst ist, sondern eine Zwischensoftware wie eine Java Virtual Machine (JVM) oder was auch immer. Aus dem Dateninhalt ist nicht ersichtlich, warum diese 1820-Byte-PDU gesendet wurde. Vielleicht war zu diesem Zeitpunkt kein 32-KB-Puffer verfügbar.

Der Punkt ist, dass es keine Rolle spielen sollte, es gibt keine wesentliche Leistungsstrafe.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.