发布于 

Wireshark: 简单分析 TCP 三次挥手

话说握手

你要是开发人员,相信你一定听说过 TCP(Transmission Control Protocol 传输控制协议)或是 TCP 握手的说法。

所谓握手,通俗来讲就是通信双方协商在后续通信过程中需要使用的通信信息的过程。TCP 为了建立可靠的连接需要三次握手,后续给大家分享 TLS 为了实现加密、校验、身份认证同样需要握手的过程。

TCP 三次握手可以使用下图来表达:

本篇给大家分享如何使用 Wireshark 来跟踪 HTTP 包,查看 TCP 握手的过程。

在看下面内容之前,先简单看一下 TCP 协议报头。

下图是 TCP 报头的格式:

其中,Seq(Sequence Number) 是 32 位的序列号,Acknowledgment number 称之为确认序号,也是 32 位的,但是他不是标志位 ACK,这个要区别开,当 ACK 置 1 时 Acknowledgment number 才有效,指接收方期待的下一个报文段的序列号。

TCP 报头信息中有六个控制位(标志位),分别是:SYN、ACK、PSH、FIN、RST 和 URG。

1
2
3
4
5
6
SYN: 表示建立连接
FIN: 表示关闭连接
ACK: 表示响应
PSH: 表示有数据传输
RST: 表示连接重置
URG: 表示紧急数据

Seq 序列号有两个作用:
第一,在 SYN 置 1 时,此为当前连接的初始序列号(Initial Sequence Number, ISN)该值是个随机值,数据的第一个字节序号为此 ISN+1。

第二,在 SYN 置 0 时,为当前连接报文段的累计数据包字节数。

TCP 协议设计比较复杂,其涉及的知识较多,这里大家整不明白也没有关系,并不影响你阅读下面的内容,如果对 TCP 协议本身感兴趣,可以去拜读【TCP/IP 详解,卷 1:协议】这本书。

网络模型

每次说到网络层,就要拿出类似下面的网络模型图,OSI 将网络模型分为7层,TCP/IP 模型将网络模型分为 4 层,网络 4 层模型由 7 层模型简化合并而来,没有本质的区别,如图:

HTTP 仅仅是个协议,属于应用层的面向对象的协议,从上图可以看出 HTTP 是在 TCP 基础之上的。

HTTP 协议一共有五大特点

1、支持客户/服务器模式
2、简单快速
3、灵活
4、无连接
5、无状态

这里强调一下 无连接无状态 这两个特点。

无连接,指的是限制每次连接只处理一个请求。服务器处理完客户端的请求,并收到客户端的应答后,即断开连接。采用这种方式可以节省传输时间。Keep-Alive 特性不在本篇讨论范围,暂时你可以将其忽略。

无状态,指的是协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。即我们给服务器发送 HTTP 请求之后,服务器根据请求,会给我们发送数据过来,但是发送完,不会记录任何信息。

可以利用 HTTP 的这两个特点来分析 TCP 三次握手的过程。

三次握手过程

三次过程如下面草图,如下所示:

我们用实际例子来看一下这个过程,以 GET 请求下面地址为例,使用 Wireshark 抓包。

1
http://www.baidu.com/news/detailV3.html?id=1279391&COMMON_ACCESS_TOKEN=(null)&COMMON_ACCESS_TOKEN_SECRET=(null)&_cT=IOS&_cV=3.1.3&_cA=PM

看返回结果,选中 HTTP/1.1 200 OK 右键, 在弹出框中选择 Follow/TCP Stream,如下图所示:

关闭弹出的弹窗,回到主界面,看到如下图所示的三次(红色 1、2、3处) TCP 握手过程:

第一次,请求客户端发送一个 [SYN] 包,序列号是 0(seq=0)。

第二次,服务器收到 [SYN] 包,然后会发送一个 [SYN, ACK] 包,序列号是 0,ACK 置 1(seq=0,ack=1)。

第三次,客户端请求服务器,客户端会发送一个 [ACK] 包,序列号是 1,Ack 置 1(seq=1,ack=1)来回复服务器。

这里注意一下,大写的 ACK 是一个 bit 位表示确认,小写的 ack 是一个确认序列号,表示数值。

简单的画一个草图,如下:

这个过程,简单描述为下面三个步骤:

双方在建立连接之前都处于 CLOSED 的状态。

1、发送方给接收方发送 SYN 信号,此时发送方处于 SYN_SENT 状态。
2、接收方确认并回复给发送方 SYN/ACK 信号,此时接收方处于 SYN_RCVD 状态。
3、发送方给接收方发送确认 ACK 信号,发送完毕后,发送方(客户端)进入 ESTABLISHED 状态,当接收端(服务端)接收到这个包时,也进入 ESTABLISHED 状态,TCP 握手结束。

上面的步骤,建议感兴趣的朋友去实际操作一下。

为什么是三次握手

回头再来想一想,TCP 的连接为什么需要三次握手呢,为什么不是一次,两次呢?一次不就挺好吗,三次是不是有点多此一举了?

TCP 协议不是一个人定出来的而是一群人拟定的,设计三次握手固然有它的意义,是经过精心设计且在性能和效率上面衡量过的。

在知乎 TCP 为什么是三次握手,而不是两次或四次? 上面有不错的答案,虽然有些回答比较搞笑,但是很好理解,比如这位仁兄:

我们不妨换个思路来想这个问题,TCP 协议设计初衷是 让数据进行可靠,高效,安全的传输,如果握手是一次,两次或四次,就无法很好的保证 TCP 的 可靠,安全及高效 的传输,说不定哪天有人设计出来一种可替代 TCP 协议的其他协议就是两次握手或者不需要握手,哈哈!

参考阅读

如何理解HTTP协议的“无连接,无状态”特点?

TCP 为什么是三次握手,而不是两次或四次?


扫码关注,你我就各多一个朋友~


本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

veryitman