TCP三次握手&四次挥手

java1234

共 2607字,需浏览 6分钟

 ·

2021-03-20 10:13

点击上方蓝色字体,选择“标星公众号”

优质文章,第一时间送达

  作者 |  EhuoWeirdo

来源 |  urlify.cn/f2YR3e

76套java从入门到精通实战课程分享

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三次握手流程


  1. B的TCP服务器进程先创建传输模块TCB,准备接受客户进程的连接请求。然后服务器进程就处于LISTEN(收听)状态,等待客户的连接请求

  2. 第一次握手:A的TCP客户进程也是首先创建传输控制模块TCB,然后向B发出连接请求报文段,此时首部中的同部位SYN = 1,同时选择一个初始序号seq = x(这个指令的意思就是告诉B客户机自己的序号是多少,要接着这个序号发送数据报)。TCP规定,SYN报文段(即SYN = 1的报文段)不能携带数据,但是要消耗一个需要。此时TCP客户进程进入SYN-SENT(同步已发送)状态

  3. 第二次握手:B收到连续请求报文段后,如同意建立连接,则向A发送确认。在确认报文段中应把SYN位和ACK位都置为1,确认号是ack = x + 1,同时自己也为自己选择一个初始序号 seq = y。(注意:这个报文段也不能携带数据,但同样需要消耗掉一个序号)。这时TCP服务器进程进入SYN-REVD(同步收到)状态

  4. 第三次握手: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四次挥手流程:


  1. 第一次挥手:A数据传输关闭,需要断开连接,A应用进程向其TCP发出连接释放报文段(FIN = 1, seq = u),并停止在发送数据,主动关闭TCP连接,进入FIN-WAIT-1状态,等待B的确认

  2. 第二次挥手:B收到连接释放报文后即发出确认报文段(ACK = 1,确认号ack = u + 1,序列号seq = v),B进入CLOSE-WAIT关闭等待状态,此时的TCP处于半关闭状态,A到B的连接释放。而A收到B的确认后,进入FIN-WAIT-2状态,等待B发出的连接释放报文段

  3. 第三次挥手:当B数据传输完毕,B发出连接释放报文段(FIN = 1, ACK = 1,序号seq = u + 1,确认号 ack = u + 1),B进入LAST-ACK(最后确认)状态,等待A的最后确认

  4. 第四次挥手:A收到B的连接释放报文段后,对此发出确认报文段(ACK = 1seq = u + 1ack = 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 秒


感谢点赞支持下哈 

浏览 32
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报