TCP 流中的数据包大小

网络工程 ipv4 通讯协议 包分析 协议理论
2021-07-13 19:15:00

我是网络流量,希望将每个 TCP 会话划分为一系列请求和响应(我正在使用的协议都以这种方式工作,例如 HTTP 或 SSL)。

我有一个简单的假设(忽略乱序和重新发送的数据包) - 给定需要发送的数据块,它将使用尽可能大的数据包发送,最后一个数据包将小于最大大小或被跟随来自另一端的数据包(忽略 ACK 空数据包)。所以在 HTTP 会话中,我希望看到类似(再次,无视 acks) -

数据包 1 - 请求“获取...”

数据包 2 - 响应,大小 1434

数据包 3 - 响应,大小 1434

数据包 4 - 响应,大小 1434

数据包 5 - 响应,大小 500

这就是我在大多数会议上得到的结果,但是我至少看到过一次看起来像

数据包 1 - 请求“获取...”

数据包 2 - 响应,大小 1434

数据包 3 - 响应,大小 1080

数据包 4 - 响应,大小 1434

数据包 5 - 响应,大小 500

没有重传、无序数据包或服务器上没有异常延迟。

我想知道 - 什么会导致这种情况,什么时候会发生?我的假设有多大错误?

更新

在这里放了一个示例 pcap 文件

更新 2

包括tshark具有相关字段转储...

$ 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 
4个回答

TCP 层使用 Nagle 算法来缓冲流量(它发送更少的大数据包,而不是更多的小数据包......使其更有效率);应用程序有一种方法可以说“立即发送”。您可以在 TCP 标头中看到带有称为 PSH(推送)位的标志。当该位由堆栈设置时,推送是在应用程序的请求下完成的。

所以这是有意的和正常的行为。

数据包大小取决于应用程序和/或操作系统如何缓冲和发送网络数据。如果应用程序和/或操作系统决定在缓冲区中有 1080 个字节后发送数据,则数据包将为 1080 个字节(加上标头)。这样做的原因可能有很多。在您的情况下,您必须查看网络服务器源代码和/或操作系统网络堆栈。

数据包大小由操作系统定义(通常),与缓冲区、应用程序提供的数据量等有关。可以使用许多策略来实现最大性能,有时发送较小的数据包可以比等待创建更快一个更大的包。

有时,运行的应用程序数量可能会要求操作系统更快(发送缓冲区中的任何内容),而不是使缓冲区饱和。

也许,您可以向我们提供有关您使用的场景的更多详细信息(例如:服务器操作系统、在其上运行的应用程序)。

从根本上说,问题在于 TCP 实现不知道应用程序接下来要做什么。当服务器应用程序进行一系列写入时,堆栈不知道它到目前为止收到的写入是整个序列还是其中的一部分。

大多数情况下,服务器应用程序写入缓冲区的速度比网络堆栈清空缓冲区的速度要快。所以缓冲区已满,完整大小的数据包出来了。

但有时其他原因会减慢服务器应用程序的速度。也许等待在过载的磁盘阵列上读取磁盘或其他东西。因此缓冲区清空,网络堆栈必须在发送较小的数据包(更多开销)或等待可能永远不会到来的数据(增加延迟)之间做出选择。