前言
介绍
目的
准备工作
传输
创建连接
握手
生成密钥
发送数据
断开连接
结论
前言
介绍
本篇文章是使用 wireshrak 对某个 https 请求的 tcp 包进行分析
目的
通过抓包实际分析了解 tcp 包
准备工作
在我自己机子上安装的是 wireshark2.2.6 版本, 随机查找了某个 TCP 连接, 并跟踪流
传输
创建连接
No58: 10.60.45.187:17932(后面简称客户端)向 131.25.61.68:443(后面简称服务端)发送了 SYN 请求连接, 此时客户端发送的 seq=0,ack=0
No79: 服务端向客户端发送了 SYN+ACK 确认连接, 此时服务端发送的 seq=0,ack=1
No81: 客户端接收到服务端的 SYN+ACK 向服务端响应 ACK 包, 此时客户端发送的 seq=0,ack=1
由于抓到的 tcp 是使用了 https 协议, 建里连接需要先进行认证, 步骤如下图所示
握手
No84: 客户端向服务端发起握手请求, 具体包格式及内容这里不做详细分析
这里 SSL 总长度为 239 字节(其中 ContentType 为 1 字节, Version 为 2 字节, Length 为 2 字节, 再加上后续握手协议长度 234)
No103: 服务端接收到客户端握手请求后响应 ACK 包, 此时 seq=1,ack=1 这个发送的是一个特殊的 TCP Window Update, 服务端告知客户端服务端有足够的缓存大小(8192), 可以正常接收客户端数据若出现了 TCP Window Full 包表示缓存区已满, 客户端会停止发送, 直到接收到了 TCP Window Update 包(Window 值表示滑动窗口, 允许接收到多个包同时响应一个 ACK 包)
No104: 服务器向客户端发送握手, 由于服务端需要返回证书算法等信息, 因此包可能会大于 1460 字节, 会发生拆包现象 (No136 可看到该包总大小为 5984KB, 拆分了 5 个包发送) 当前服务端发送的 seq=1,ack=240(当前包大小为 1460,No84 说明客户端包大小为 239)
No105: 服务器向客户端发送握手数据, 这个包标记的是
TCP Previous segment not captured
, 说明发送包可能出现了乱序或丢包现象, 这个包的 seq=2921, 而 No104 的下一个包 seq 应该为 1461,No104 和 No105 中间 seq=1461 的包可能丢包或乱序传输
No106: 服务器向客户端发送握手数据, 这个包的 seq=4381, 因为 No105 的下一个包的 seq 和这个包一样, 所以这两个包是按顺序传输的当前包的下一个包 seq=5841
No108: 这个包是客户端向服务端发送的一个 ACK 其中 ack=1461, 表示客户端确认收到了 No104 这个包
No118: 服务器向客户端发送 ACK 包, 这个包标记的是 TCP Out-Of-Order, 由于 No105 包显示出现了丢包现象, 因此 tcp 将 No104 以前的包全部重传, 这个包实际就是 No104
No119: 客户端向服务端发送 ACK 包, 这个包标记的是 TCP Dup ACK 108#1, 表示重传 ACK 包, 这个包是由于 No118 包引起的(#N 表示重传 N 次, 这里重传了 1 次), 因为 No118 包服务端向客户端发送了一个乱序的包, 而客户端在 No108 包已经确认接收到 No104 这个包, seq 应该为 1461, 所以, 客户端再一次重传 108 包告知服务端客户端已经接收到 No104 包
No123 和 No124: 服务器向客户端发送握手数据, 包标记的是 TCP Retransmission, 两个包的 seq 分别为 1461 和 2921, 由于服务端认为已经发了这两个包(实际 seq=1461 的包没发, 由 No105 可看出, seq=2921 的包发了, 但是客户端没有响应响应的 ACK 包), 然后长时间收不到客户端的 ACK 包, 因此服务端会重发这两个包
No127: 客户端向服务端发送 ACK 包 seq=240,ack=5841, 表示已经接收到服务端 seq=5841 以前的所有包由于 TCP 协议拥有受时延的确认机制(No103 的滑动窗口就是干这个用的), 即收到一个包可能并不会立刻返回 ACK 包, 收到多个包可能只返回一个 ACK 包, 这样可以减少网络传输
No132: 服务器向客户端发送握手数据, 包标记的是
TCP Spurious Retransmission
, 表示这个包已经发送过该报的 seq=1461, 即 No123 重传的包, 虽然客户端向服务端发送了 ACK 包收到了 seq=5841 以前的包, 但是服务端可能没有收到这个 ACK 包
No133: 客户端向服务端发送 ACK 包 seq=240,ack=5841 包标记的是 TCP Dup ACK 127#1 由于客户端在 No127 已经返回了 ack=5841, 但是服务端在 No132 还是重传了之前已经传过的包, 所以客户端认为 No127 包可能服务端没有收到, 所有这里重传了 No127 这个 ACK 包
No136: 服务端向客户端发送的最后一个握手包 seq=5841 下个包 seq=5985, 在这包汇总了 5 个分段包内容和信息
No140: 客户端向服务端发送 ACK 包 seq=240,ack=5985
生成密钥
No141: 客户端接收到服务端的握手请求后, 生成密钥对发送给服务端由于 No103 开始的包都是服务端向客户端发送数据, 因此客户端的 seq 一直是 240
No147: 服务端向客户端重发 No136 包因为 No140 这个包客户已经确认收到 seq=5985 以前的包了, 因此服务端发的这个包发生了虚假重传
No148: 客户端向服务端发送 ACK 包这个包标记为 TCP Dup ACK 140#1 是由于 No147 这个包服务端发生虚假重传, 因此客户端重新发送 No140 包
No152: 服务端向客户端发送, 包标记为
Change Cipher Spec, Encrypted Handshake Message
, 这是对握手信息进行加密
No153: 客户端向服务端发送 ACK 包, 接收到了 No152 包
发送数据
No154-No159: 客户端向服务端发送数据
No166 和 No167: 服务端向客户端发送了 2 个 ACK 包
No170: 服务端向客户端发送数据
No171: 客户端发送给服务端 ACK 包, 确认收到 No170 这个包
No178: 服务端向客户端发送数据, 这个包是 No170 分段后剩余的数据
No179: 客户端发送给服务端 ACK 包, seq=8331,ack=8770, 确认收到 No178 这个包
No152 到 No179 都是正常传输的包, 这里不做详细分析了
断开连接
No180: 客户端接收完服务端数据后就断开连接了, 所以发送了一个 FIN 包, 同时客户端进入到 FIN_WAIT_1 状态
理论上服务端发送完就主动关闭 http 连接, 但是抓包看确是客户端先发送的 FIN+ACK 包, 因此说明服务端发送的 FIN+ACK 的包可能丢包, 客户端没收到或收到慢了
No187: 服务端发送客户端 FIN+PSH+ACK,seq=7552,ack=8331 这包不但传了 FIN 关闭连接, 又传了 PSH 说明 No178 包服务端发出来, 客户端返回的 ACK 包 (No179 以及 No180) 服务端没收到(这中间可能网络处理问题)
No188: 由于 No187 包标记为 TCP Out-Of-Order, 因此客户端认为服务端的包乱序了, 因此, 因此客户端重传 No179
No189: 服务端接收到客户端的 FIN 包, 也接受到 No188 包, 返回客户端一个 ACK 包, seq 也更新成最新的 8770, 客户端进入 FIN_WAIT_2 状态
No198: 服务端发送给客户端 RST 重置连接, 可能是由于 No179 到 No187 之间网络出现了问题, 导致连接异常, 因此服务端发送了一个 RST 重置连接
结论
上面抓的包经分析可能出现多次网络异常或网络波动, 出现了乱序, 重传, 虚假重传及连接重置等 TCP 包
若分析有误, 希望加以指正
来源: https://www.cnblogs.com/Jack-Blog/p/8486792.html