TCP流中的数据包大小


10

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

我有一个简单的假设(忽略乱序和重发的数据包)-给定需要发送的数据块,它将使用最大可能的数据包发送,最后一个数据包小于最大大小或遵循来自另一侧的数据包(忽略ACK空数据包)。因此,在HTTP会话中,我希望看到类似的内容(再次,不考虑Ack)-

数据包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 

可能有很多原因...窗口大小可能太小(尽管在您的情况下不太可能),可能没有足够的数据要发送(脚本生成了输出吗?),生成数据的软件可能明确地刷新它,等等
桑德Steffann

@SanderSteffann,窗口大小似乎无关紧要,固定间隔一定很久。整个响应是一个javascript,因此我认为它不是由另一个脚本生成的。
Vadim

@vadim,能否请您发布一个屏幕截图或更好的截图,即指向具有1080字节有效负载的pcap的超链接?
Mike Pennington

@MikePennington-感谢您的输入,我将在几个小时内提供指向pcap文件的链接。
Vadim

@MikePennington-我已经添加了一个指向pcap文件的链接来演示这一点。
Vadim 2013年

Answers:


6

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

因此,这是正常的行为。



完全正确,应该在原始RFC中完成,而WAS在winsock和套接字上所做的工作
fredpbaker 2013年

在查看了pcap之后,网络服务器不太可能在OP的流量上设置PSH
Mike Pennington

3

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


我看到很多数据包的最大大小,只有这个大小较小,所以它不是某种默认值。可能是服务器打h了-它被卡在其他东西上了一个延迟,足以使网络堆栈决定发送缓冲区中的内容吗?
Vadim

当然可以。如果不调试服务器及其运行的操作系统,就无法判断。但是,恕我直言,这没什么可惊的。
塞巴斯蒂安·维辛格

我没有惊慌,这看起来很奇怪,我想知道是否还有更多的东西。
Vadim

1
如果您有接线,请在1080数据包的TCP标头中查找PSH(推送)位。那就是应用程序堆栈说现在发送此数据。
fredpbaker

1
参见上文,它是大多数情况下的TCP堆栈
fredpbaker

1

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

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

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


0

从根本上讲,问题是TCP实现不知道应用程序下一步将要做什么。当服务器应用程序执行写入序列时,堆栈不知道到目前为止接收到的写入是整个序列还是仅一部分。

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

但是有时其他原因会使服务器应用程序变慢。也许正在等待在过载的磁盘阵列上读取磁盘或其他东西。因此,缓冲区为空,并且网络堆栈必须在发送较小的数据包(增加开销)或等待可能永远不会出现的数据(增加延迟)之间进行选择。


0

如果查看第34帧,您将看到服务器已发送了32kB缓冲区,并且PSH位置1。如果查看82,则从前一个PSH位开始将看到相同的32 kB。即使响应少于2kB,数据包52仍具有PSH位。

PSH位通常由TCP堆栈为写入网络的应用PDU的最后一段设置。因此,应用程序使用32kB缓冲区,并且在有大量数据时,一次将其写入TCP套接字32kB。当第51-52帧中的数据较少时,这是因为应用程序在响应中首先写出了该记录,并且只有1820字节。

请注意,我所指的应用程序实际上可能不是服务器应用程序本身,而是某些中间软件,例如Java虚拟机(JVM)或其他。从数据内容还不清楚为什么发送了1820字节的PDU,也许当时没有32kB的缓冲区?

关键是没关系,没有实质性的性能损失。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.