本篇文章是使用wireshrak对某个https请求的tcp包进行分析。算法
经过抓包实际分析了解tcp包。缓存
在我本身机子上安装的是wireshark2.2.6版本,随机查找了某个TCP链接,并跟踪流。
服务器
SYN
请求链接,此时客户端发送的seq=0,ack=0。SYN+ACK
确认链接,此时服务端发送的seq=0,ack=1。No81:客户端接收到服务端的SYN+ACK
向服务端响应ACK
包,此时客户端发送的seq=1,ack=1。网络
因为抓到的tcp是使用了https协议,建里链接须要先进行认证,步骤以下图所示。
tcp
No84: 客户端向服务端发起握手请求,具体包格式及内容这里不作详细分析。
加密
这里SSL总长度为239字节(其中
ContentType
为1字节,Version
为2字节,Length
为2字节,再加上后续握手协议长度234。)。.net
ACK
包,此时seq=1,ack=1。这个发送的是一个特殊的TCP Window Update
,服务端告知客户端服务端有足够的缓存大小(8192),能够正常接收客户端数据。若出现了TCP Window Full
包表示缓存区已满,客户端会中止发送,直到接收到了TCP Window Update
包。(Window值表示滑动窗口1,容许接收到多个包同时响应一个ACK包)No104: 服务器向客户端发送握手,因为服务端须要返回证书、算法等信息,所以包可能会大于1460字节,会发生拆包现象(No136可看到该包总大小为5984KB,拆分了5个包发送)。当前服务端发送的seq=1,ack=240(当前包大小为1460,No84说明客户端包大小为239。)
3d
TCP Previous segment not captured
,说明发送包可能出现了乱序或丢包现象,这个包的seq=2921,而No104的下一个包seq应该为1461,No104和No105中间seq=1461的包可能丢包或乱序传输。ACK
其中ack=1461,表示客户端确认收到了No104这个包。ACK
包,这个包标记的是TCP Out-Of-Order
,因为No105包显示出现了丢包现象,所以tcp将No104之前的包所有重传,这个包实际就是No104。ACK
包,这个包标记的是TCP Dup ACK 108#1
,表示重传ACK包,这个包是因为No118包引发的(#N表示重传N次,这里重传了1次),由于No118包服务端向客户端发送了一个乱序的包,而客户端在No108包已经确认接收到No104这个包,seq应该为1461,因此,客户端再一次重传108包告知服务端客户端已经接收到No104包,这个包实际服务端已经接收到了所以会被丢弃。TCP Retransmission
,两个包的seq分别为1461和2921,因为服务端认为已经发了这两个包(实际seq=1461的包没发,由No105可看出,seq=2921的包发了,可是客户端没有响应响应的ACK包),而后长时间收不到客户端的ACK包,所以服务端会重发这两个包。ACK
包。seq=240,ack=5841,表示已经接收到服务端seq=5841之前的全部包。TCP Spurious Retransmission
,表示这个包已经发送过。该报的seq=1461,即No123重传的包,虽然客户端向服务端发送了ACK
包收到了seq=5841之前的包,可是服务端可能没有收到这个ACK包。ACK
包。seq=240,ack=5841。包标记的是TCP Dup ACK 127#1
。因为客户端在No127已经返回了ack=5841,可是服务端在No132仍是重传了以前已经传过的包,因此客户端认为No127包可能服务端没有收到,全部这里重传了No127这个ACK包,这个包服务端已经接收到了,所以会被丢弃。No140:客户端向服务端发送ACK
包。seq=240,ack=5985。
code
ACK
包。这个包标记为TCP Dup ACK 140#1
是因为No147这个包服务端发生虚假重传,所以客户端从新发送No140包。Change Cipher Spec, Encrypted Handshake Message
,这是对握手信息进行加密。No171: 客户端发送给服务端ACK包,确认收到No170这个包。
No179: 客户端发送给服务端ACK包,seq=8331,ack=8770,确认收到No178这个包。
No152到No179都是正常传输的包,这里不作详细分析了。
FIN
包,同时客户端进入到FIN_WAIT_1
状态。理论上服务端发送完就主动关闭http链接, 可是抓包看确是客户端先发送的
FIN+ACK
包,所以说明服务端发送的FIN+ACK
的包可能丢包,客户端没收到或收到慢了。
FIN+PSH+ACK
,seq=7552,ack=8331。这包不但传了FIN
关闭链接,又传了PSH
。说明No178包服务端发出来,客户端返回的ACK包(No179以及No180)服务端没收到(这中间可能网络处理问题)。TCP Out-Of-Order
,所以客户端认为服务端的包乱序了,所以,所以客户端重传No179。FIN
包,也接受到No188包,返回客户端一个ACK
包,seq也更新成最新的8770,客户端进入FIN_WAIT_2
状态。上面抓的包经分析可能出现屡次网络异常或网络波动,出现了乱序,重传,虚假重传及链接重置等TCP包。
若分析有误,但愿加以指正。
本文地址:http://www.javashuo.com/article/p-ztvcbzns-bd.html
做者博客:杰哥很忙
欢迎转载,请在明显位置给出出处及连接
使用TCP的滑动窗口协议时,接收方没必要确认每个收到的分组。在TCP中,ACK是累积的—它们表示接收方已经正确收到了一直到确认序号减1的全部字节。↩