Wireshark理解TCP乱序重组和HTTP解析渲染
TCP数据传输过程
TCP乱序重组原理
HTTP解析渲染
TCP乱序重组
TCP具有乱序重组的功能。
(1)TCP具有缓冲区
(2)TCP报文具有序列号
所以,对于你说的问题,一种常见的处理方式是:TCP会先将报文段3缓存下来,当报文段2到达时,再根据序列号进行拼接。
2 当然缓冲区也有满的时候,这时接收端会直接丢弃报文,不做任何其他处理;
发送方的定时器发现迟迟收不到接收方丢弃报文的确认号(ack number),就会重传该报文。这就是TCP的超时重传功能
Sequence Number是包的序号,用来解决网络包乱序(reordering)问题。
Acknowledgement Number就是ACK——用于确认收到,用来解决不丢包的问题。
MTU: Maxitum Transmission Unit 最大传输单元
MSS: Maxitum Segment Size 最大分段大小
对于建链接的3次握手,主要是要初始化Sequence Number 的初始值。通信的双方要互相通知对方自己的初始化的Sequence Number(缩写为ISN:Inital Sequence Number)——所以叫SYN
全称Synchronize Sequence Numbers。也就上图中的 x 和 y。
这个号要作为以后的数据通信的序号,以保证应用层接收到的数据不会因为网络上的传输的问题而乱序
(TCP会用这个序号来拼接数据)。
网络文件时流量巨大,出现很多
TCP segment of a reassembled PDU
其实主机响应一个查询或者命令时如果要回应很多数据(信息)而这些数据超出了TCP的最大MSS时,
主机会通过发送多个数据包来传送 这些数据(注意:这些包并未被分片)
。对wireshark来说这些对相应同一个查询命令的数据包被标记了“TCP segment of a reassembled PDU”
问题,wireshark如何识别多个数据包是对同一个查询数据包的响应?
wireshark是根据sequence number来识别,这些数据包ACK number是相同的,
当然number的数值与查询数据包中的next sequence number也是一样的。
对于TCP协议而言就不一样了,这个协议是面向连接的协议,
对于TCP协议而言它非常在意数据包的到达顺序以及是否传输中有错误发生。所以有些TCP应用对分片有要求---不能分片(DF)。
这个还是取决于对TCP协议的理解,参照TCP序列号和确认号详解,讲解很清晰
基于自己理解
重点讲数据传输过程:
TCP数据传输过程
1) 发送数据:服务器向客户端发送一个带有数据的数据包,该数据包中的序列号Seq和确认号Ack与建立连接第三步的数据包中的序列号和确认号相同;
如上图Seq=1 ACK=1
2) 确认收到:客户端收到该数据包,向服务器发送一个确认数据包,该数据包中,序列号是为上一个数据包中的确认号值,而确认号为服务器发送的上一个数据包中的序列号+所该数据包中所带数据的大小。
如上图Seq=1 Ack=999 Seq(x)=Ack(y) 1 Ack(x)=Seq(x)+998 (data len) 999 c——》s
Seq=999 Ack=1381 Seq(y)=Ack(x) 999 Ack(y)=Seq(y)+1381(data len) 1381 s——》c
Seq=1381 Ack=999 Seq(x)=Ack(y) 1381 Ack(x)=Seq(x)+998 (data len) 999 c——》s
Seq=999 Ack=2761 Seq(y)=Ack(x) 999 Ack(y)=Seq(y)+1381(data len) 2761 s——》c
SeqNum的增加是和传输的字节数相关的, 数据分段中的序列号Seq可以保证所有传输的数据按照正常的次序进行重组,而且通过确认保证数据传输的完整性。
上图中,三次握手后,来了两个Len:1381的包,而第二个包的SeqNum就成了1381。然后第一个ACK回的是1381,表示第一个1381收到了,第二个Ack回的是 2761,表示第二个1381收到了
注意:1.Wireshark使用了Relative SeqNum——相对序号,以便更容易观察,在protocol preference 中取消掉就可以看到“Absolute SeqNum”。
2.服务器端处理一次客户端请求,发送的多个数据包的ACK是相同的,如上,均为999
3.ack递增,seq连接(开始的位置),只需要Seq即可重组。
TCP乱序重组原理
对于乱序和拥塞,TCP的处理:
Tcp引入快速重传机制,不以时间驱动而是以数据驱动重传。如果包没有连续到达,就ack可能被丢了的包,如果发送方连续收到3次相同的ACK,就重传,这样就不等timeout就重传了。而且对于乱序报文不丢弃,而是缓存下来(减少重传)立即发送希望接受的报文确认。
例子:
发送端A发送了以下几个包:第一个:1001-1100,第二个1101-1200,第三个FIN包(序列号是1201,一个虚字节)。
1)第二个包在传输的过程中丢失了,接收端收到第三个包后并不丢弃,而是缓存下来,然后,立即发送一个ACK,确认号是1101(这样做的目的是不必等到发送端A的第二个包超时后重传,发送端A收到3个同样的ACK后立即重传,这是快速重传的概念)。
2)当发送端A收到3个确认号都是1101或者第二个包的超时计时器到时间后,立即重新发送第二个包(之所以可以重传,是因为TCP协议在接收端和发送端都各自建立了两个发送、接收缓存)。
3)这样,当接收端B收到来自A的第二个包后,缓存中的数据都是按序的了。
4)对于按序包,接收端B对序列号的最后一个字节+1,也就是发送确认号是1202的ACK包。
5)发送端A收到确认号是1202后,便不能再发送任何数据了。
快速重传:
如果发送方发出了1,2,3,4,5份数据,第一份先到送了,于是就ack回2,结果2因为某些原因没收到,3到达了,于是还是ack回2,后面的4和5都到了,但是还是ack回2,因为2还是没有收到,于是发送端收到了三个ack=2的确认,知道了2还没有到,于是就马上重转2。然后,接收端收到了2,此时因为3,4,5都收到了,于是ack回6。
接收端收到每个包,都要发送ACK给服务器端,那么如果是乱序的话,在接收端做判断,发送乱序的包的ACK给服务器,(在wireshark中体现为duplicate ACK ),表示收到一个出问题的分片,TCP立即产生一个应答,这个相同的ACK不会延迟,以告诉服务器端知道一个分片被收到的时候出现问题,并且告诉它希望得到的序列号,服务器如果收到这样三次相同的ACK包,则立即重传。但是重传成功前,又出现这样的情况,那么丢失的不止一个包,但服务器收到的ACK依然没有增长。
对于上面的示例来说,是重传#2呢还是重传#2,#3,#4,#5呢?因为发送端并不清楚这连续的3个ack(2)是谁传回来的?也许发送端发了20份数据,是#6,#10,#20传来的呢。这样,发送端很有可能要重传从2到20的这堆数据(这就是某些TCP的实际的实现)。
猜测是在接收端根据序列号进行排序,一接收到重传的数据包便进行重组,并且seq number增加,马上发ACK给服务器端。
在127 125位置乱序
服务器发送过来的seq按照顺序来递增,客户端的seq根据接收到的数据包正确的顺序来递增,ack根据上一次数据包的序列号+这次传输数据包的大小来递增,如果接收到有问题的包,则seq和ack不变,每次都发送相同的seq和ack给服务器端,如71和73.包括之后收到seq不按顺序递增的包,客户端还是发送相同的ack给服务器端,所以服务器端识别不了具体是哪个有问题的数据包发送的,只跟初始有问题的数据包有关系。
返回服务器端的确认编号实际上是客户端希望收到的序列号。
duplicate ACK。接下来几个报文重复此过程,直到接收到缺失的数据包
TCP Previous Segment Lost,看Frame流程,17940--20699的包没有按序到达,而后发的包竟然先到了,乱序了,后续127重传的包就是缺少的包。
71和73的seq和ack是一样的
接收到125的数据包后,ack递增,估计是在客户端进行重组后的结果,发送ack表示已经重组好多少数据,服务器继续发送以起始位置为17941的数据包,即为127。至此,在127之前的数据已经重组完毕。
另外,如果标记为 “TCP out of order”,则是后到的包,一般不超过“TCP Dup Ack **#3”(?)。
HTTP解析渲染
刚开始认为http在发出请求后,会并发建立TCP连接,连接数基本不变,但实际情况并非如此,这就涉及到浏览器对HTTP的加载、解析、渲染的过程:
- 用户访问网页,DNS服务器(域名解析系统)会根据用户提供的域名查找对应的IP地址,找到后,系统会向对应IP地址的网络服务器发送一个http请求。
- 网络服务器解析请求,并发送请求给数据库服务器。
- 数据库服务器将请求的资源返回给网络服务器,网络服务器解析数据,并生成html文件,放入http response中,返回给浏览器。
- 浏览器解析 http response。
- 1~4步骤需要了解HTTP协议。
- 访问服务器端可能遭遇的问题:如果网络服务器无法获取数据库服务器返回的资源文件(http response 404),或者由于并发原因暂时无法处理用户的http请求(http response 500)
- 浏览器解析 http response后,需要下载html文件,以及html文件内包含的外部引用文件,及文件内涉及的图片或者多媒体文件。
加载:当浏览器获得一个html文件时,“自上而下”加载,加载过程中进行解析渲染。
资源间互相阻塞
IE下载的顺序是从上到下,渲染的顺序也是从上到下,下载和渲染是同时进行的。在渲染到页面的某一部分时,其上面的所有部分都已经下载完成(但并不是说所有相关联的元素都已经下载完。)在下载过程中,如果遇到某一标签是嵌入文件,并且文件是具有语义解释性的(例如:JS脚本,CSS样式),那么此时IE的下载过程会启用单独连接进行下载。并且在下载后进行解析,解析(JS、CSS中如有重定义,后定义函数将覆盖前定义函数)过程中,停止页面所有往下元素的下载。样式表文件比较特殊,在其下载完成后,将和以前下载的所有样式表一起进行解析,解析完成后,将对此前所有元素(含以前已经渲染的)重新进行样式渲染。并以此方式一直渲染下去,直到整个页面渲染完成。