您现在的位置是:首页 >技术杂谈 >【TCP 协议】连接管理之 “三次握手,四次挥手”网站首页技术杂谈

【TCP 协议】连接管理之 “三次握手,四次挥手”

保护小周ღ 2024-06-14 17:17:26
简介【TCP 协议】连接管理之 “三次握手,四次挥手”

哈喽,大家好~我是你们的老朋友:保护小周ღ  


本期为大家带来的是网络编程中的 TCP 传输控制协议保证数据可靠性传输的机制之一的——连接管理,通信双方采用 “三次握手” 来建立连接,采用 “四次挥手” 会断开连接,如何进行 ”握手” 和 “挥手” 操作,本文将为您解析~~


本期收录于博主的专栏JavaEE_保护小周ღ的博客-CSDN博客

适用于编程初学者,感兴趣的朋友们可以订阅,查看其它 “JavaEE基础知识”。
更多精彩敬请期待:保护小周ღ *★,°*:.☆( ̄▽ ̄)/$:*.°★* ‘


一、上期回顾

1.1 TCP 的报文结构

 争对TCP 报文重点做简单的解析:

序号和确认号:各占 32个二进制位 用于实现数据的可靠传输,所传送的字节流的每一个字节都会按顺序编号,保证数据传输的顺序和接收的顺序一样。序号表示当前发送的数据包的序号,确认号表示期望接收的下一个数据包的序号。序列号和确认号存在的意义就在于保证数据传输的顺序和接收的顺序一样。           

标志位:包括ACK、SYN、FIN、RST、PSH、URG六种各占一个二进制位。

默认置为 0 ,如果为标志位置为 1表示 true 的意思。

ACK:用于确认收到数据包;

SYN:判断通信双方是否建立了连接;

FIN:用于关闭连接;0

RST:用于重置连接;

PSH:用于提示接收方立即将数据推送给应用程序,而不是进入接收缓冲区;

URG:用于指示TCP包中有紧急数据。


1.2 确认应答和超时重传

确认应答:

当接收方收到发送方的发送的数据时,会给予发送方一个带有 TCP 首部的字段反馈,其中ACK = 1(一个二进制位), 表示我已经收到数据。 

针对以上机制,就有三种情况:

1. 数据直接在传输的过程中丢失,接收方没有收到数据,也就无法给予反馈。

2. 接受方收到数据后,给予发送方反馈,然而反馈报文在传输过程中丢了。

3. 当发送方一定时间没有接收到反馈,就会触发超时重传,然后重传的数据也丢了

超时重传:

如果发送方一定时间内没有等到接收方反馈的确认应答,就会对该段“数据包” 进行重传,期间如果还是没有接收到反馈发送方就会降低重传的频率过超一定的次数,TCP 就尝试给通信双发重新建立连接,如果连接失败,就会终止本次的网络通信。

这里的重新建立连接和终止本次网络通信的具体如何实现,是本文的主题~~

具体内容,大家可以阅读博主的上一篇博客:【TCP 协议】报文格式,数据可靠传输的机制(一)_保护小周ღ的博客-CSDN博客


二、连接管理

TCP 传输层协议,协议功能:保证通信双方数据可靠性传输。

保证的重要因素就是确认应答和超时重传的机制,接收方收到数据收会给予发送方反馈,这个反馈就是带有 TCP 固定首部的字段,TCP 首部中包含标志位信息,每一个标志位只占一个二进制位,所以根据 TCP 首部的标志位,我们就可以判断出当下TCP 数据包 的一个状态

TCP协议通信双方连接是通过三次握手来建立的。


2.1 三次握手

握手(handshake)指的是通信双方们,进行了网络交互,发送方和接收方之间,通过三次交互,建立了连接关系。连接关系指的是:通信双方各自记录了彼此的信息~

为什么提客户端和服务器呢,因为我们日常生活中的通信,通信双方并不是直接建立连接,而是先与服务器建立连接,信息通过服务器的 “中转”。

建立连接的 “意愿 ”一定是客户端主动先发起的

  1. 客户端向服务器发送SYN包,表示请求建立连接。

  2. 服务器收到SYN包后,回复一个SYN+ACK包,表示同意建立连接。

  3. 客户端收到SYN+ACK包后,再回复一个ACK包,表示连接建立成功。

SYN : (一个二进制位)置1 意思是一方要向另一方申请连接。表示当前 TCP 数据报是一个同步报文。

ACK : 一个二进制位),置1 意思是给予反馈,确认收到数据。表示当前 TCP 数据报是一个应答报文。

通信双方建立连接示意图:

博主这里采用了,打电话的场景模拟了一下 "建立连接" ,或许这样的通话有一定时间的前摇,但是主要的目的是——验证通信双方,各自的发送能力和接收能力是否正常,确认了交互过程的正常,这也是后续数据可靠性传输的基础。

为啥是三次握手,二次行不行,四次行不行?

首先两次握手,只能确认一方的 收发功能正常。

多次的握手呢,把中间的 AYN 和 ACK 拆分,分别发送,同样可以达到验证的目的,但是完全没有必要,因为一个 TCP 的数据段,需要经过层层的封装和分用(TCP / IP 五层通信模型),分两次发送,效率就显得很低。


2.3. 四次挥手

四次挥手就是通信双方断开连接,也是取一个很好听的名字。

断开连接的 “意愿” ,客户端和服务器都有可能发起。

  1. 客户端向服务器发送FIN包,表示要断开连接。

  2. 服务器收到 FIN 包后,回复一个 ACK 包,表示已经收到断开请求。

  3. 服务器再发送一个FIN包,表示同意断开连接。

  4. 客户端收到FIN包后,回复一个ACK包,表示已经收到断开请求。

FIN: (一个二进制位)置1 意思是一方要向另一方申请断开连接表示当前 TCP 数据报是一个结束报文。

通信双方断开连接示意图:

通过以上流程,断开连接的就是,通信双方各自给对方发送一个 FIN (结束报文),再各自给对此发送一个 ACK(应答报文)。

学习了 “三次握手” 之后,我们会发现有一个操作 SYN + ACK ,请求连接 + 确认应答,两个标志位可以在同一TCP 数据报中反馈,从而有了 三次交互


但是在断开连接这里, FIN 和 ACK 却是分开来传输的,所以断开连接就需要 通信双方进行 四次交互。

原因就是,SYN + ACK 都是由操作系统内核完成的,可以在同一时机触发。

TCP 属于传输层协议,作为程序开发者来说,重点关注的其实是应用层的开发,只是选择使用基于 TCP 协议 Socket 接口(API) 来开发。 传输层-网络层-数据链路层-物理层, 这 4 层实际上已经被操作系统封装好了,层层调用嘛,所以应用层直接使用传输层协议提供的接口,也就不需要太关注其他内部实现。

四次挥手 :

ACK  与 FIN 是不同的机触发的,ACK 由系统内核完成,所以在收到 FIN - 断开连接的请求之后,第一时间就会给发送方给予-确认应答。

FIN - 断开连接,是由应用程序代码控制的,在 Java 网络编程中,在调用 Socket (接口),中的 close() 方法时,才会触发 FIN ——  发送一个 TCP 数据报 FIN 置为 1 的结束报文。

例如:服务器在发现客户端发送了一个结束报文,所以就自己调用了 close() 方法,从而触发第二个结束报文。当然什么使用调用 close()方法这就根据程序是怎么写的。


关于程序没有调用 close() 触发结束报文的情况

例如:在客户端的程序,压根没写 close() , 这种情况,服务端给客户端发出结束请求 FIN ——服务器 接收不到客服端 反馈的结束报文。是不是连接就断开不了啊,不不不

如果将客户端的程序结束-进程结束-应用程序结束- 比如 qq 结束运行, 自动会触发 "close()", 资源会随着进程的结束而结束,由系统控制回收,因此就会触发 FIN 结束报文。此时客户端的 qq 应用程序运行结束了,但是 TCP 的连接还在(由操作系统内核维护),直到与 qq 服务器完成四次挥手~ 反之同理。

需要注意的是,TCP协议是全双工的,即客户端和服务器可以同时发送和接收数据。因此,在断开连接时,需要进行四次挥手,操作系统内核维护挥手过程以确保双方都已经断开连接。


好了,到这里,网络编程中的 【TCP 协议】连接管理之 “三次握手,四次挥手” 博主已经分享完了,希望对大家有所帮助,如有不妥之处欢迎批评指正。 

感谢每一个观看本篇文章的朋友,更多精彩敬请期待:保护小周ღ *★,°*:.☆( ̄▽ ̄)/$:*.°★* 

遇见你,所有的星星都落在我的头上……

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。