TCP 连接管理概述
TCP 是面向连接的协议. 运输连接是用来传送 TCP 报文的. TCP 的连接和释放是每一次面向连接的通信中必不可少的过程. 因此, 运输连接就有三个阶段, 即: 连接建立, 数据传输和连接释放. 运输连接的管理就是使运输连接的建立和释放都可以正常的进行.
在 TCP 连接的建立过程中要解决一下三个问题.
1. 要使每一方能够确知对方的存在.
2. 要允许双方协商一些参数(如窗口最大值, 是否使用窗口扩大选项和时间戳选项以及服务质量等).
3. 能够对运输实体资源 (如缓存大小, 连接中的项目等) 进行分配.
TCP 连接的建立采用客户服务器方式. 主动发起建立连接的应用叫做客户(Client), 而被动等待连接建立的应用进程叫做服务器(server).
TCP 连接的建立
下图表示的是 TCP 连接建立的过程. 主机 A 运行的是 TCP 客户端程序, 而 B 运行 TCP 服务器端程序. 最初的时候, 双方的 TCP 进程都处于关闭 (CLOSED) 状态. 然后 A 主动打开连接, 而 B 被动打开连接.
1.A 发送一个 SYN=1 的 TCP 报文, 序列号 seq 是 x.A 的状态由 CLOSED 进入到 SYN-SENT.
2.B 收到之后发送 SYN=1,ACK=1 的 TCP 报文, 同样为自己选一个序列号 seq=y, 确认号 ack=x+1.B 的状态由 LISTEN 进入到 SYN-RCVD.
3.A 收到 B 的确认之后, 需要给 B 确认. ACK=1,seq=x+1, 确认号 ack 是 y+1.A 的状态由 SYN-SENT 进入到 ESTABLISH,B 在收到 A 的确认之后也由 SYN-RCVD 进入到 ESTABLISH.
以上的过程就是 3 次握手. 这里一个常见的问题就是为什么在 A 发送建立连接的请求后还需要发送一个确认报文? 这是因为主要是为了避免已经失效的连接请求报文段突然又传到了 B 而产生错误. 失效的报文主要是在出现在网络不是很通畅的时候会产生, 而三次握手机制避免了这种情况会产生的问题.
TCP 连接的释放
在传输结束之后, 通信双方都可以释放连接. A 的应用进程先向其 TCP 发出连接释放报文段, 并停止发送数据, 主动关闭 TCP 连接.
1.A 将连接释放报文的终止控制位 FIN 设置为 1,seq 序列号为 u. 此时 A 的状态由 ESTABLISH 进入到 FIN-WAIT-1.
2.B 在收到这个报文之后, 随即发出确认. ACK=1 seq=v ack=u+1. 此时 B 由 ESTABLISH 进入到 CLOSE-WAIT 状态. A 收到 B 的确认之后进入到 FIN-WAIT-2. 此时 B 的 TCP 服务器进程会通知高层应用进程. 这个时候 A 到 B 的传输就释放了, TCP 的连接处于半关闭状态. A 没有数据发送到 B, 若 B 还有数据, 可以发送到 A.
3.B 发送 FIN=1 ACK=1 seq=w ack=u+1(必须重复上次的确认号).B 由 CLOSE-WAIT 进入到 LAST-ACK 状态.
4.A 收到 B 的连接释放报文之后, 发送确认 ACK=1 seq=u+1 ack=w+1. 此时 A 由 FIN-WAIT-2 进入到 TIME-WAIT.B 在收到 A 的确认之后由 LAST-ACK 进入 CLOSED 状态. A 在 2MSL(大约是 4 分钟)之后进入到 CLOSED 状态.
这里一个常见的问题就是 A 为什么需要 2MSL 的等待时间. 第一是为了保证 A 最后发送的 ACK 报文到达 B. 第二是为了当时出现上文提到的失效的报文段. 因为 2MSL 会使本次连接产生的报文段都从网络中消失.
全文完.
来源: https://juejin.im/post/5c2c95476fb9a049ec6b2fdb