TCP-Connection

TCP 连接建立与结束

建立连接(三次握手)

连接建立的过程

  1. 请求端(通常也称为Client 客户)发送一个带有SYN标识符以ISN + 1为序列号的TCP报文段给另一端(通常也称为Server 服务器)请求建立一个TCP连接
  2. Server如果能够建立TCP连接,则发回一个带有ACK标识符同时确认序号为Client序列号 + 1的确认报文段给Client。
  3. Client发送一个新的带有ACK标识符同时确认序号为Server序列号 + 1的报文段给Server进行确认 (很多情况下,Client已经开始在这个报文段中的数据块中塞入将要发送给Server的数据)。
    至此,三次握手完毕,TCP连接建立。

连接建立超时

很明显,有很多种异常情况可能导致TCP连接无法建立。比如说Server没有处于正常状态;又或者装载TCP报文段的IP数据报在转发的过程中丢失了。
TCP协议对这种情况的处理方式是,为TCP连接建立设置一个超时时间,在超时时间到来之前会发送多个SYN包请求建立对端建立TCP连接。在超时时间到来之后,如果连接还没有建立,则放弃建立连接。

结束连接 (四次握手)

建立一个TCP连接需要三次握手,而完全终止TCP连接却需要4次。因为TCP连接是全双工的,一个FIN报文段一次只能关闭一个方向上的数据传送。因此,想要完全关闭一条TCP连接,需要两对FIN - FIN的ACK 报文段配对才行。这一种情况也被称为TCP连接的半关闭

发送FIN关闭TCP连接通常是应用层进行关闭的结果!

若在应用主动关闭连接的时候对设备进行抓包,可以很清楚的看到主动关闭方发送了一个带有FIN标识符的报文段给另一方。

TCP连接半关闭

图中虽然被动关闭方(第一个FIN的接受方)看起来在接收到FIN的ACK之后立即发送了自己的FIN给对端。但其实,在很多情况下这两个报文段之间是有时间间隔的,而在时间间隔中还发送了很多数据报文段,用以发送还未发送的数据。这一现象就是TCP的半关闭。
而TCP协议允许的这样一个“窗口期”特性,很多时候也被加以利用。(譬如Client已经发送完了自己将要发送的数据,但是仍然想要接收Server发送的数据)

同时打开 & 同时关闭

由于TCP是全双工的,因此双方同时请求对端建立连接或者同时关闭连接是可能的。但是由于出现的概率很小,同时应用的场景很少,这里就不过多介绍了。

RST

请求建立连接端口不存在

经常会出现这种情况,请求建立连接的SYN报文段已经发送到了Server,但是Server检查到对应的目的端口并没有被监听(该端口绑定的应用程序没有启动)。这个时候Server在发送回给Client的ACK包中便会将RST标识符置1,用以通知Client连接无法建立。

异常终止连接

通过发送RST而不是发送FIN报文段来结束TCP连接的方式也被称为异常释放。通常在某一个端在接收到对端发来不正常的报文时会发回一个RST给对端异常终止连接。这里讲的不正常可能不是报文段的内容有问题,而是无法处理该报文段。(在TCP保活定时器中应用中,在Client重启之后收到旧TCP连接对端服务器发来的探查报文段时,就会发回一个RST包让服务器终止连接。)
这样的异常终止连接有两个好处:

  • 不需要执行四次握手,RST的接收端在收到该报文段之后将直接关闭。(RST的发送端之所以发送RST报文很可能是因为自己根本不能执行正常的四次握手来关闭TCP连接)
  • RST的接收端知道对端出现了异常情况,从而进入到相应的异常处理流程