图解TCP连接建立与释放(三次挥手四次握手)

参考:计算机网络微课堂——湖科大

TCP连接的建立(三握)

  • TCP是面向连接的协议,它基于运输连接来传送TCP报文段
  • TCP运输连接的建立和释放时每一次面向连接的通信中必不可少的过程
  • TCP运输连接建立有以下三个阶段:
    TCP运输连接建立有三个阶段:

这三个阶段就是我们听说最久的:
三次挥手建立连接、建立连接后进行数据传输、四次挥手释放TCP连接

  • TCP的运输连接管理就是使用运输连接的建立和释放都能正常的进行

TCP的连接建立要解决以下三个问题:

  1. 使TCP双方都能确知对方的存在
  2. 使TCP双方能够协商一些参数(如窗口最大值、是否使用窗口扩大选项和时间戳选项和服务质量等等)
  3. 使TCP双方能够对运输实体资源(如缓存大小、连接表中的项目等)进行分配

图解连接过程

具体过程:

三次握手最开始双方状态

在三报文握手过程中,有两个角色客户端发送握手连接请求,服务器等待接收请求。


在最开始:双方都是处于关闭状态,此时双方的TCP进程都是关闭的。

此时,服务器在连接之前要进行准备
TCP服务器进行准备

准备过程中,服务器创建传输控制块,在块中有TCP连接表等一些TCP连接的重要信息。创建后便开始监听,准备接收来自客户端的连接请求。

值得注意的是:

TCP服务器进程是被动等待来自TCP客户进程的连接请求。而不是主动发起,因此称为被动打开连接。

与服务器类似,客户端进程也需要进行准备:

客户端进程进行准备

其准备过程只有建立传输数据块。

准备完毕后开始”握手“:

第一次发送握手报文:

第一次发送握手报文

在打算建立TCP连接时,客户端向TCP服务器进程发送TCP连接请求报文段,并进入同步已发送状态


TCP连接请求报文段首部中,有两个关键数据:

  1. 同步位SYN被设置为1表明这是一个TCP连接请求报文段

  2. 序号字段seq:被设置了一个初始值x,作为TCP客户端进程所选择的初始序号

请注意:TCP规定SYN被设置为1的报文段不能携带数据,但要消耗掉一个序号

服务器收到信号后,发送第二次握手报文:

服务器收到信号后

TCP服务器进程收到客户端发送的TCP连接请求报文段后,如果同意建立连接,则向TCP客户进程发送TCP连接请求确认报文段,并进入同步已接收状态


TCP连接请求确认报文段首部中有几个关键数据位:


同步位SYN和确认为ACK:都设置为1,表明这是一个TCP连接请求确认报文段。


序号字段seq:设置了一个初始值y,作为TCP服务器进程所选择的初始序号


确认号字段ack:值被设置成了x+1,这是对TCP客户进程所选择的初始序号(seq)的确认


值得注意的是:这个报文段也不能携带数据,因为它是SYN被设置为1的报文段,但同样要消耗掉一个序号

发送方接收到确认报文后,开始第三次握手:

发送方进行第三次握手

TCP客户进程收到TCP连接请求确认报文段后,还要向TCP服务器进程发送一个普通的TCP确认报文段,并进入连接已连接状态


普通的TCP确认报文段首部中有以下重点数据位:


确认位ACK:设置为1,由于没有SYN同步字段,表明这是一个普通的TCP确认报文段,表示已确认收到建立连接报文。


序号字段seq:设置为x+1,因为TCP客户进程发送的第一个TCP报文段的序号为x,所以TCP客户进程发送的第二个报文段的序号为x+1(SYN字段报文需要消耗一个序号)


确认号字段ack:设置为y+1,这是对TCP服务器进程所选择的初始序号的确认
值得注意的是:TCP规定普通的TCP确认报文段(只有ACK没有SYN)可以携带数据,但如果不携带数据,则不消耗序号

三次握手完毕

三次握手完毕后,服务器也进入连接已建立状态,此时双方连接已建立,可以开始进行数据传输。

这里有一个问题:

为什么TCP客户端进行最后还要发送一个普通的TCP确认报文段呢?是否多余?

答案是否定的。

  • 三次握手建立连接是为了防止已经失效的连接请求报文段突然又传到服务端,产生错误

例如,下面采用两次握手就建立连接:

两次握手建立连接示例

客户端发出去了第一个连接请求报文并没有丢失,但是由于某种原因造成了较长时间的迟到现象


此时发送端重新开始发送请求连接报文,并且通过两次握手成功建立连接,没有进行请求序号的验证


在传输完数据之后,通过四次挥手释放连接。此时双方处于关闭连接状态


但是此时,已经迟到多时的请求报文到达了服务器,本来这是一个早已失效的报文段,但是服务器收到此失效的报文之后,会误认为是客户端再次发出的一个新的连接请求


于是服务器就向客户端又发出确认报文,表示同意建立连接。此时服务器处于连接状态,而客户端由于处于关闭状态,不会接收该确认报文。


如果不采用“三次握手”服务端接收到客户端发出的请求报文就会认为要请求建立新的连接,并且进入连接状态,但是客户端此时可能并没有发出建立连接的请求,该报文是由于某种情况迟到的请求,因此不会去向B端发送数据,服务端没有收到数据就会一直等待


这样子会造成服务端白白浪费掉很多资源。

综上所诉,三次握手并不多余,这是为了防止已失效的连接请求报文段突然又传送到了TCP服务器,因而导致错误。

总结:

三次握手总结

TCP连接的建立释放(四挥)

  • TC通过四报文挥手来释放连接

连接图解释放过程

以下图解说明:

数据建立主动释放

在双方连接已建立后,此时需要客户端主动发出关闭信号

第一次挥手:
第一次挥手

TCP客户进程发送TCP连接释放报文段,并进入终止等待1状态


TCP连接释放报文段首部中有以下关键数据位:


终止位FIN和确认位ACK:值都被设置为1表明这是一个TCP连接释放报文段,同时也对之前收到的报文段进行确认


序号seq字段:值设置为u,u等于TCP客户进程之前已传送过的数据的最后一个字节的序号加1,用来表示发送过程中的最后一个字节序号为u。


确认号ack字段:值设置为vv等于服务器进程之前发送的数据中最后一个字节的序号加1,也就是确认收到已经收到的服务器发送的数据

  • 请注意:TCP规定终止位FIN等于1的报文段即使不携带数据,也要消耗掉一个序号

第二次挥手:
第二次挥手

接收方再接收到连接释放报文后,会发送一个普通的TCP确认报文段并且进入关闭等待状态


普通的TCP确认报文段首部中有以下关键数据位:
确认位ACK:值被设置为1,表明这是一个普通的TCP确认报文段。


序号seq值设置为v,v等于TCP服务器进程之前已传送过的数据的最后一个字节的序号加1与之前收到的TCP连接释放报文段中的确认号ack值匹配


确认号ack字段:值为u+1,这是对TCP连接释放报文段的确认,也就是为发送方连接释放报文中的seq的值+1.

第二次挥手后服务器状态

在进行第二次挥手后,会产生以下过程:


TCP服务器进程通知高层应用进程TCP客户进程要断开与自己的TCP连接,此时的TCP连接进入半关闭状态


所谓半关闭状态可以认为,此时客户端与服务器的连接不再传输数据,也就是客户端没有数据在发生。而此时服务器若有剩余数据要发送会继续发送。客户端到服务器这一信道关闭了,而服务器到客户端这一半没有关闭,因此称为半关闭状态


这个半关闭状态可能会持续一段时间,直到发送方没有数据进行发送。

在以上等待过程中,客户端会进入终止等待2状态
终止等待2状态
此时当服务器没有数据要传输后。进行第三次挥手:
第三次挥手

此时TCP服务器进程会发送TCP连接释放报文段并进入最后确认状态。


在该报文段中有以下关键数据段:


终止位FIN和确认位ACK:值都被设置为1,表明这是一个TCP连接释放报文段,同时也对之前收到的报文段进行确认


序号seq:值为w,因为在半关闭状态下,TCP服务器进程可能又发送一段数据,因此w就是该段数据最后的序号


确认号ack:值为u+1,这是对之前收到的TCP连接释放报文段的重复确认,因此值与发送方第一次挥手发送的seq值+1

TCP客户进程收到TCP连接释放报文段后开始第四次挥手:第四次挥手

此时针对第三次挥手的报文段发送普通的TCP确认报文段,之后进入时间等待状态


该报文段首部中有以下关键数据位:


确认位ACK:值被设置为1,表明这是一个普通的TCP确认报文段


序号seq字段:值设置为u+1,用来表示最后一个发送的字节序号,但是为何没有发送数据,而此时值要设置为u+1(对比第一次挥手数据)?,因为TCP客户进程之前发送的TCP连接释放报文段(带有FIN)虽然不携带数据,但要消耗掉一个序号


确认号ack:值设置为w+1,这是对所收到的TCP连接释放报文段的确认

此时,TCP服务器进程收到该报文段后就进入关闭状态,而TCP客户进程还要经过2MSL后才能进入关闭状态:

可独断经过2MSL后才能进入关闭状态

MSL具体的值可以根据TCP协议的不同实现进行设置。

至此,三次握手四次挥手过程结束!



此时就会出现一个问题:

  • 为什么不发送报文段后直接关闭,而是要等待2MSL个时间后才关闭?是否有必要?

答案是有必要

考虑以下情况:

不等待2MSL的情况

若客户端发送完最后一次报文后,也就是第四次挥手后就直接进入关闭状态,此时若第四次挥手报文丢失,会导致服务器的超时重传


此时客户端又已经关闭,导致不接受该报文,因此服务器会一直不断重传,并一直处于最后确认状态无法进入关闭状态


因此,有以下结论
客户端进入时间等待状态以及处于该状态2MSL时长,可以确保TCP服务器进程可以收到最后一个TCP确认报文段而进入关闭状态


TCP客户进程在发送完最后一个TCP确认报文段后,在经过2MSL时长,就可以使本次连接持续时间内所产生的所有报文段都从网络中消失,这样就可以使下一个新的TCP连接中,不会出现旧连接中的报文段

若出现这样一种情况:

TCP双方已经建立了连接,但是传输过程中TCP客户进程所在的主机出现了故障,此时TCP服务器进程以后就不能再收到TCP客户进程发来的数据,这时服务器进程会一直处于等待状态。

为了使TCP服务器进程不要再白白等待下去出现了TCP保活计时器:

TCP保活计时器:
在这里插入图片描述


如果觉得文章写的还不错,麻烦点个赞支持一下,欢迎评论,互相交流学习。

猜你喜欢

转载自blog.csdn.net/Nimrod__/article/details/113717891