简介
本文介绍TCP的三次握手和四次挥手。即:TCP建立连接和断开连接的过程。
三次握手
流程图

主机 A为客户端,主机B为服务端。
正式的流程描述
- 第一次握手
- A 发送同步报文段(SYN) 请求建立连接。
- A进入SYN-SENT(同步已发送)状态。
- 第二次握手
- B 监听到连接请求, 向 A 发送针对 SYN 的确认 ACK, 同时 B 也发送自己的请求建立连接(SYN) 。
- B进入SYN-RCVD (同步收到)状态
- 第三次握手
- A 收到 B 发出的 SYN,给出确认应答 ACK。
- A 收到确认后进入 ESTABLISHED (己建立连接)状态。B 收 到 A 的确认后,也进入ESTABLISHED状态
通俗的流程描述
A:向B发送数据:我想跟你(B)建立连接,收到请回复。
B:向A响应数据:好的,可以建立连接。你收到信息后请确认一下,我就跟你建立连接。
A:收到B的确认,将状态置为已连接。向B响应数据:好了,我收到了,请你建立连接吧。
B:收到A的确认,将状态置为已连接。
TCP为什么要三次握手而不是两次
如果是 2 次(即:没有第3次握手)
- 网络延迟导致服务端建立连接,而客户端没建立连接
- 客户端发出一个请求报文段,它滞留在了某个网络节点, 过了好长时间才发送到服务端, 此时服务端建立连接。 但是由于现在客户端并没有发出连接请求, 因此不会理睬服务端的确认, 而服务端以为新的连接产生, 服务端的资源被浪费。
- 如果服务端的ACK丢失,会导致客户端一直重试,服务端会连接大量无效连接
- 当服务端的确认应答 ACK 总是丢失时, 客户端以为服务端没有连接, 它将会不断地重新请求连接,而服务端会连接大量的无效连接, 给服务器增加维护成本, 服务器很容易受到 SYN 洪水攻击。
四次挥手
流程图

正式的流程描述
- 第一次挥手
- 当主机 A 发送数据完毕后, 发送 FIN 结束报文段。
- 第二次挥手
- 主机 B 收到 FIN 报文段后, 向主机 A 发送一个确认序号 ACK(为防止这段时间内, 对方重传 FIN 报文段) 。
- 第三次挥手
- 主机 B 准备关闭连接, 向主机 A 发送一个 FIN 结束报文段。
- 第四次挥手
- 主机 A 收到 FIN 结束报文段后, 进入 TIME_WAIT 状态。 并向主机 B 发送一个ACK 表示连接彻底释放。
通俗的流程描述
A:向B发送数据:我想跟你(B)断开连接,收到请回复。
B:向A响应数据:好的,准备断开连接,不过我还有些数据没发送完,我发送完之后跟你说。
B:向A响应数据:断开连接吧,我数据处理完了,收到请回复,我收到你的回复后也会断开连接。
A:收到B的确认,开始断开连接。向B响应数据:好了,我收到了,请你断开连接吧。
B:收到A的确认,将状态置为已断开
TCP为什么是四次挥手
- 当客户端发送 FIN 结束报文段时,服务端并不会立即关闭 SOCKET(服务端会先通知应用进程,应用进程再关闭),所以只能先发送一个 ACK。(因为有可能此时服务端还有数据没发送完)
请先
!