Alex_McAvoy

想要成为渔夫的猎手

TCP 连接管理

【概述】

TCP 是面向连接的协议,因此,每一个 TCP 连接都有三个阶段:连接建立数据传送、连接释放

TCP 连接管理,就是使 TCP 连接的建立与释放能够顺利进行

TCP 将连接作为最基本的抽象,每一条 TCP 连接都有两个端点,端点使用套接字(Socket)作为接口,也就是说,每一条 TCP 连接被通信两端的两个套接字唯一确定

TCP 连接的建立方式采用客户/服务器式,主动发起连接的应用进程被称为客户机,被动等待连接建立的应用进程被称为服务器

【TCP 连接建立】

TCP 连接建立又称三次握手,经历以下三个步骤:

1.客户机发送 TCP 连接请求

当客户机想要建立 TCP 连接时,会向服务器发送一个 TCP 连接请求报文段

这个 TCP 连接请求报文段不含应用层数据,即该 TCP 报文段只有 TCP 首部,不携带任何数据

虽然该报文段不携带数据,但要消耗掉一个序号,即客户机会随机选择一个起始序号 seq=x

此外,TCP 连接请求报文段中的同步位 SYN=1

2.服务器收到 TCP 连接请求,若同意建立,就发回确认

在服务器收到 TCP 连接请求报文段后,若同意建立连接,会向客户机发送一个 TCP 确认报文段,该报文段同样不携带任何数据,但也要消耗掉一个序号,即客户机会随机选择一个起始序号 seq=y

同时,在 TCP 确认报文段中,确认位 ACK=1,同步位 SYN=1,确认号 ack=x+1

此外,在服务器发送完 TCP 确认报文段后,该服务器会为该连接分配 TCP 缓存与变量

3.客户机收到 TCP 确认,发回该确认的确认

在客户机收到 TCP 确认报文段后,会向服务器发送一个 TCP 确认报文段,即确认的确认

在该 TCP 确认报文段中,确认位 ACK=1,同步位 SYN=1,确认号 ack=y+1,序号 seq=x+1

此外,在客户机发送完 TCP 确认报文段后,该客户机会为该连接分配 TCP 缓存与变量

在经历以上三步后,TCP 连接就建立了,接下来就可以传送应用层数据,同时,由于 TCP 提供的全双工通信,因此,通信双方的应用进程在任何时间都可以发送数据

要注意的是,服务器的资源是完成第二次握手时分配的,客户端的资源是完成第三次握手时分配的,这使得服务器易受 SYN 洪泛攻击

【TCP 连接释放】

TCP 连接的释放又称四次挥手,需要经历四个步骤,参与 TCP 连接的两个进程中的任何一个都能终止该连接,下面以客户机提出主动关闭连接为例,说明 TCP 连接释放过程

1.客户端发送 TCP 释放请求

当客户端打算关闭连接后,会向服务器发送一个 TCP 连接释放报文段,并停止发送数据,主动关闭 TCP 连接

TCP 连接释放报文段,不携带任何数据,但也要消耗掉一个序号,序号为前面已经传输的数据的最后一个字节的序号 $+1$,这里假设为 seq=u

同时,终止位 FIN=1,表明客户端的数据已发送完毕,并要求释放 TCP 连接

需要注意的是,由于 TCP 是全双工的,当客户端发送 TCP 连接释放报文段后,其只是单方面关闭了客户端到服务器方向的连接,服务器方仍可发送数据

2.服务器收到 TCP 释放请求,发回确认

服务器收到来自客户端的 TCP 连接释放报文段后,会立即对该报文段发回确认

对于发回的TCP 确认报文段来说,不携带任何数据,但也要消耗掉一个序号,序号为前面已经传输的数据的最后一个字节的序号 $+1$,这里假设为 seq=v

同时,其确认位 ACK=1,确认号 ack=u+1

此时,从客户机到服务器方向的连接彻底释放,TCP 连接处于半关闭状态,服务器方仍可发送数据

3.服务器发送 TCP 释放请求

若服务器已经没有要向客户机发送的数据,会向客户机发送 TCP 连接释放报文段,并停止发送数据,主动关闭连接

对于该 TCP 连接释放报文段来说,同样不携带任何数据,但也要消耗掉一个序号,序号为前面已经传输的数据的最后一个字节的序号 $+1$,这里假设为 seq=w

同时,其终止位 FIN=1,确认位 ACK=1,确认号 ack=u+1

4.客户机收到 TCP 释放请求,发回确认

客户机收到来自服务器的 TCP 连接释放报文段后,会立即对该报文段发回确认

对于发回的 TCP 确认报文段来说,其确认位 ACK=1,确认号 ack=w+1,序号 seq=u+1

此时,TCP 连接并没有完全释放掉,只有当服务器收到该确认后,服务器端才进入连接关闭状态,而对于客户端来说,必须等待超时计时器设置的 2MSL 后,才进入连接关闭状态


之所以客户端要等待 2MSL,有以下两个原因:

  1. 保证客户端发送的最后一个 TCP 确认报文能够到达服务器端
  2. 防止已失效的连接请求报文段出现在本连接中,使下一新的连接中不会出现这种旧的连接请求报文段

感谢您对我的支持,让我继续努力分享有用的技术与知识点!