文章目录
📚概述
“什么是三次握手,四次挥手?”,该问题作为计算机网络学科中常见问题之一,无论是面试还是考研,我们都有必要细细参透其中的奥妙
在学习之前,我们首先需要了解一些基本的概念
📚基础理论
📐传输控制协议
传输控制协议(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,在 OSI 模型中完成传输层指定功能。
TCP 使用校验和函数检验数据是否出现错误,在数据发送和接收时均需要计算校验和。
✒️TCP 特点
1.TCP 是面向连接的传输层协议
应用程序在使用 TCP 协议前,必须首先完成 TCP 连接的建立。在数据传输结束后,必须释放先前已建立的 TCP 连接
2.每一条 TCP 连接只能有两个端点
TCP 连接只能是点对点,一对一的
3.TCP 提供可靠交付服务
通过 TCP 连接传送的数据,无差错、不丢失、不重复,且按序到达
4.TCP 提供全双工通信
TCP 允许通信双方的应用进程在任何时候都可以发送数据,TCP连接的两端都设有发送、接收缓存,用于临时存放双向通信的数据,上层应用进程在时机恰当时会读取缓存中的数据
5.TCP 面向字节流
图 1 TCP 面向字节流示意图 |
流是指:流入到进程或从进程流出的字节序列
TCP 把应用程序回传的数据看做一连串的无结构的字节流,不保证接收方应用程序所收到的数据块和发送方应用程序所发出的数据块具有对应大小的关系
接收方应用程序收到的字节流必须和发送方应用程序发出的字节流完全一致,且接收方的应用程序必须具有识别接收字节流,并将其还原为有意义的应用层数据的能力
✒️TCP 报文首部
这里需要了解 TCP 报文首部的格式,相关控制位非常重要
图 2 TCP 报文首部的格式示意图 |
由于 TCP 报文段首部的前 20 个字节是固定的,其后 4n 个字节是根据需要增加的选项,所以 TCP首部的最小长度是 20 字节
1.源端口和目的端口
各占 2 字节,分别写入源端口号、目的端口号
2.序号字段
占 4 字节,范围为
[0,2 ^ 32-1]
,序号使用mod2^32
运算,在一个TCP连接中传送的字节流中的每一个字节都按顺序编号。整个要传送的字节流的起始序号必须在连接建立时设置,首部中的序号字段值则指的是本报文段所发送的数据的第一个字节的序号
3.确认号字段
占4字节,是期望收到对方下一个报文段的第一个数据字节的序号。若确认号等于 N,则表明:到序号 N-1 为止数据均己正确接收
4.数据偏移字段
占 4 位,指出 TCP 报文段的数据起始处和 TCP 报文段的起始处的距离。此字段实际上指出了 TCP 报文段的首部长度
5.保留字段
占 6 位,保留为今后使用,目前应置为0
6.紧急 URG
URG=1时,表明紧急指针字段有效,它告诉系统此报文段中有紧急数据,应尽快传送,即提高数据传送的优先级
7.确认 ACK
仅当 ACK=1 时确认号字段才有效,TCP 规定,在连接建立后所有传送的报文段必须将 ACK 置为 1
8.推送 PSH
接收 TCP 收到 PSH=1 的报文段后,将尽快交付接收的应用进程,不再等到缓存都填满后再继续向上交付
9.复位 RST
当 RST=1 时,表明 TCP 连接中出现严重差错,必须释放连接,然后再重新建立传输连接。也可以用于拒绝一个非法的报文段或拒绝打开一个连接
10.同步 SYN
连接建立时用来同步序号,SYN=1就表示这是一个连接请求或连接接受报文
11.终止 FIN
用于释放一个连接,当 FIN=1 时,表明此报文段的发送方的数据己发送完毕,并要求释放传输连接
12.窗口字段
占 2 字节,窗口值范围为
[0,2^16-1]
之间的整数。窗口是指发送本报文段的一方的接收窗口,窗口值作为接收方让发送方设置其发送窗口的依据
13.检验和字段
占 2 字,检验和字段检验的范围包括首部和数据两部分
14.紧急指针
占 2 字节,仅当 URG=1 时才有意义,含义是:本报文段中的紧急数据的字数,紧急指针指出了紧急数据的末尾在报文段中的位置
当所有紧急数据都处理完时,TCP就告诉应用程序恢复到正常操作。注意:即使窗口为零时也可发送紧急数据
15.选项字段
长度可变,最长可达 40 字节。未使用“选项”时,TCP 首部长度为 20 字节
📚TCP 连接的建立与释放
📐三次握手
TCP
建立连接的过程称为握手,握手需要在客户端和服务器之间交换三个 TCP
报文段
我们举一个简单的例子帮助大家理解这个问题:试想下面这个场景
你出门在外没带钥匙,而房屋钥匙又仅有一把,在不考虑钥匙丢失在哪里的情况下,今晚你还会回家吗?
虽然此例子并不那么恰当,但是可以类比到三次握手的原因上。如果客户端和服务端有一方出现了问题,那么它们之间的通讯、资源传输必定会出问题
因此,TCP
三次握手的作用就是使客户端和服务端双方都明确自己的责任,保证双方都具有资源接收和发送的能力
图 3 TCP 三次握手示意图 |
字符释意:
ACK
:确认报文段ack
:确认号SYN
:发送连接请求 / 接收报文段`seq
:发送数据的第一个字节的序号
客户端与服务端资源收发的三次握手过程如下:
*注:图例中的 Ss
、Sa
分别表示 Server send
、Server accept
(服务端发送能力、服务端接收能力);Cs
、Ca
分别表示 Client send
、Client accept
(客户端发送能力、客户端接收能力)
1.第一次握手
第一次握手由客户端发送资源包给到服务端,若该过程正常,则得出结论:服务端接收、客户端发送服务正常
图 4 TCP 建立连接第一次握手示意图 |
2.第二次握手
第二次握手由服务端发送资源包给到客户端,若该过程正常,则得出结论:服务端发送、客户端接收服务正常
图 5 TCP 建立连接第二次握手示意图 |
3.第三次握手
这里大家可能就会有疑问了?为什么还需要进行第三次握手呢?前两次不是已经得出结论客户端、服务端接收、发送资源包能力正常了吗?
其实并不是,第一、二次握手只是在单独的过程中得出服务正常的结论,但是在第二次握手结束后,服务端的接收能力和客户端的发送能力未知,这时候便有了 TCP
的第三次握手过程
第三次握手由客户端发送资源包给到服务端,若该过程正常,则得出结论:服务端接收、客户端发送服务正常
图 6 TCP 建立连接第三次握手示意图 |
通过这三次的握手过程我们可以分析得到:第二次是对第一次握手的补充,第三次是对第二次握手的补充,最终正好形成闭环,客户端和服务端都确认了自己的接收、发送能力正常,之后方可进行通信
并且,要完成两者状态的监测,这之间至少需要三次过程,两次并不足以判断自身的服务状态。每一个步骤都相互关联,下一次握手的“响应”由上一次“请求“触发,每次握手得出的结论都是对上一次结果的补充,从而得出最终结果
三次握手过程中,客户端和服务端交换 Initial Sequence Number (ISN
),为了使对方清除下一步接收到的数据信息应以何序列号进行数据整合
并且,ISN 在此过程中是动态生成的。假如 ISN 固定不变,入侵者非常容易就能得出后续数据的确认号,这将会危机到数据信息的安全
📐四次挥手
当成功建立一个 TCP
连接, 服务端在 LISTEN
状态下,收到建立连接请求的 SYN
报文后,将 ACK
和 SYN
存放到同一个报文中一起发送给客户端
而关闭连接时,服务端收到客户端的 FIN
报文时,仅表示对方不再发送数据,但仍然能够接收数据。此时,服务端不一定将全部数据都发送给了客户端
因此服务端关闭有两种方式:
- 立即关闭
- 继续发送一些数据给客户端后,再发送
FIN
报文给客户端(表示同意关闭连接),是否立刻关闭发送数据通道,需交由上层应用决定
所以,客户端的 ACK
和 FIN
一般都会分开发送,这里就会导致次数增加一
数据传输完毕后,双方均可释放连接。起初,客户端和服务端均处于 ESTABLISHED
状态,然后是客户端主动关闭,服务器被动关闭
整个过程请参考下图:
图 7 TCP 释放连接四次挥手示意图 |
字符释意:
FIN
:连接终止位seq
:发送的第一个字节的序号ACK
:确认报文段ack
:确认号
四次挥手过程:
- 客户端发送第一次挥手,之后由
ESTABLISHED
状态转为FIN_WAIT1
状态 - 服务器收到客户端的第一次挥手之后,发送第二次挥手给服务器,服务器进入
CLOSE_WAIT
状态,等待服务器自身的SOCKET
关闭等处理 - 客户端收到服务器的第二次挥手,进入
FIN_WAIT2
状态,等待服务器关闭 - 服务器发送第三次挥手,然后进入
LAST_ACK
状态 - 客户端收到第三次挥手,发送第四次挥手,客户端进入
TIME_WAIT
状态; - 服务器收到第四次挥手,进入
CLOSED
状态,客户端等待 2MSL 后,进入CLOSED
状态
TCP 状态转换过程见下图:
图 8 TCP 状态转换过程示意图 |
📚总结
TCP
建立连接的三次握手是指发送了三个报文段,而 TCP
断开连接进行四次挥手是指发送了四个报文段,在此过程中,SYN
和 FIN
均利用重传进行可靠传输
连接的释放本质上两次就可以完成,但若想要完全释放,则需要四次挥手,请看下图
图 9 TCP 连接释放举例 |
打电话即将结束时,路人甲说完信息“OK,我没事了”后,路人乙回复到“嗯,知道啦”。这是就是完成了 TCP 四次挥手的前两次过程;路人乙马上要挂断电话时,路人甲又忽然想起来某件事,说了很多。这时路人乙又回复到“好的好的”。至此,TCP 四次挥手的后两次过程完毕