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

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

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

数据包2-响应,大小1434

数据包3-响应,大小1434

数据包4-响应,大小1434

数据包5-响应,大小500

我在大多数会议中得到的是什么,但是至少有一次我看到了类似的情况

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

数据包2-尺寸为1434的响应

数据包3-尺寸为1080的响应

数据包4-尺寸为1434的响应

数据包5-大小为500的响应

没有重新传输,这里的数据包乱序或服务器上没有异常的延迟。

我想知道-是什么原因引起的,何时发生? ?我的假设有多错误?

UPDATE

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

UPDATE 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 


评论

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

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

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

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

@MikePennington-我已经添加了一个指向pcap文件的链接,以证明这一点。

#1 楼

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

所以这是正常现象。

评论


澄清点...应用程序无法直接控制PSH位...

–迈克·彭宁顿
2013年9月1日13:47



完全正确,这是应该在原始RFC中完成的,并且WAS在winsock和套接字上做了什么

– fredpbaker
2013年9月1日19:12在

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

–迈克·彭宁顿
2013年9月2日7:01

#2 楼

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

评论


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

–Vadim
13年8月31日在16:22

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

–塞巴斯蒂安·维辛格
13年8月31日在16:26

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

–Vadim
13年8月31日在16:54

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

– fredpbaker
13年8月31日在17:58



见上文,在大多数情况下是TCP堆栈

– fredpbaker
2013年9月2日,下午1:48

#3 楼

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

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

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

#4 楼

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

大多数时候,服务器应用程序执行写入缓冲区的速度快于网络堆栈清空缓冲区的速度。因此,缓冲区已满,并且有完整大小的数据包出来。

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

#5 楼

如果查看第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的缓冲区?

要点是,这无关紧要,没有实质性的性能损失。