TCP三次握手&四次挥手
共 2607字,需浏览 6分钟
·
2021-03-20 10:13
点击上方蓝色字体,选择“标星公众号”
优质文章,第一时间送达
作者 | EhuoWeirdo
来源 | urlify.cn/f2YR3e
1、TCP概述
网络分为IOS七层协议:物理层、数据链路层、网络层、传输层、会话层、表现层、应用层
TCP协议属于传输层的协议
1.1TCP数据包结构图
在进行握手时,就依赖着结构中的序号和确认号
1.2TCP中的标识符
SYN:同步标志
同步序列编号(
Synchronize Sequence Numbers
)栏有效。该标志仅在三次握手建立TCP连接时有效。它提示TCP连接的服务端检查序列编号,该序列编号为TCP连接初始端(一般是客户端)的初始序列编号。在这里,可以把TCP序列编号看作是一个范围从0到4,294,967,295的32位计数器。通过TCP连接交换的数据中每一个字节都经过序列编号。在TCP报头中的序列编号栏包括了TCP分段中第一个字节的序列编号
ACK:确认标志
确认编号(
Acknowledgement Number
)栏有效。大多数情况下该标志位是置位的。TCP报头内的确认编号栏内包含的确认编号(w+1,Figure-1)为下一个预期的序列编号,同时提示远端系统已经成功接收所有数据
URG:紧急标志
紧急(
The urgent pointer
) 标志有效,紧急标志置位
FIN:结束标志
带有该标志置位的数据包用来结束一个TCP会话,但对应端口仍处于开放状态,准备接收后续数据
三次握手Three-way Handshake
2、三次握手
一个虚拟连接的建立是通过三次握手实现的
2.1示意图
2.2三次握手流程
B的TCP服务器进程先创建传输模块TCB,准备接受客户进程的连接请求。然后服务器进程就处于
LISTEN
(收听)状态,等待客户的连接请求第一次握手:A的TCP客户进程也是首先创建传输控制模块TCB,然后向B发出连接请求报文段,此时首部中的同部位
SYN = 1
,同时选择一个初始序号seq = x
(这个指令的意思就是告诉B客户机自己的序号是多少,要接着这个序号发送数据报)。TCP规定,SYN报文段(即SYN = 1
的报文段)不能携带数据,但是要消耗一个需要。此时TCP客户进程进入SYN-SENT
(同步已发送)状态第二次握手:B收到连续请求报文段后,如同意建立连接,则向A发送确认。在确认报文段中应把
SYN
位和ACK
位都置为1,确认号是ack = x + 1
,同时自己也为自己选择一个初始序号seq = y
。(注意:这个报文段也不能携带数据,但同样需要消耗掉一个序号)。这时TCP服务器进程进入SYN-REVD
(同步收到)状态第三次握手:TCP客户进程收到B的确认后,还要向B给出确认。确认报文段的ACK置1,确认号
ack = y + 1
,而自己的序号seq = x + 1
。TCP的标准规定,ACK报文段可以携带数据。但如果不携带数据则不消耗序号,在这种情况下,下一个数据报文段的序号仍是seq = x + 1
。这时,TCP连接建立,A进入ESTABLISHED
(已建立连接)状态,当B收到A的确认消息后,也进入ESTABLISHED
状态
注:最后一次握手在默认不携带数据的情况下,由于SYN不是1,是不消耗序列号的。所以三次握手结束后,客户端下一个发送的报文中
seq
依旧是x + 1
2.3为什么需要三次握手,而非两次?
为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤
如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认
3、四次挥手
一个虚拟连接的断开是通过四次挥手实现的
3.1示意图:
3.2四次挥手流程:
第一次挥手:A数据传输关闭,需要断开连接,A应用进程向其TCP发出连接释放报文段(
FIN = 1, seq = u
),并停止在发送数据,主动关闭TCP连接,进入FIN-WAIT-1状态,等待B的确认第二次挥手:B收到连接释放报文后即发出确认报文段(
ACK = 1
,确认号ack = u + 1
,序列号seq = v
),B进入CLOSE-WAIT关闭等待状态,此时的TCP处于半关闭状态,A到B的连接释放。而A收到B的确认后,进入FIN-WAIT-2状态,等待B发出的连接释放报文段第三次挥手:当B数据传输完毕,B发出连接释放报文段(
FIN = 1
,ACK = 1
,序号seq = u + 1
,确认号ack = u + 1
),B进入LAST-ACK(最后确认)状态,等待A的最后确认第四次挥手:A收到B的连接释放报文段后,对此发出确认报文段(
ACK = 1
,seq = u + 1
,ack = w + 1
),A进入TIME-WAIT(时间等待)状态,此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,A才进入CLOSE状态
3.3为什么A在TIME-WAIT状态必须等待2MSL(最大报文生存时间)的时间?
为了保证A发送的最后一个ACK报文段能够到达B,保证A、B正常进入CLOSED状态
这个ACK报文段有可能丢失,使得处于LAST-ACK状态的B收不到对已发送的FIN+ACK报文段的确认,B超时重传FIN+ACK报文段,A能2MSL时间内收到这个重传的FIN+ACK报文段,接着A重传一次确认,同时重启2MSL计数器,2MSL时间后A和B进入CLOSE状态,如果A在TIME-WAIT状态时接收到B的FIN+ACK报文段之后向B发出确认报文段,而不再确认B是否收到立即进入CLOSED状态,如若B并没有正常收到A 的确认报文段,则B无法正正常进入到CLOSED状态
粉丝福利:Java从入门到入土学习路线图
👇👇👇
👆长按上方微信二维码 2 秒
感谢点赞支持下哈