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 tshark
Dumps 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
Antworten:
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.
quelle
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.
quelle
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).
quelle
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).
quelle
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.
quelle