TCP 协议的特点、三次握手建连、四次挥手断连

文章目录

  • TCP 协议的特点
  • TCP 三次握手建连
  • TCP 四次挥手断连

TCP 协议的特点

  1. 位于 OSI 模型的第四层:传输层

  2. 面向连接

    TCP 是基于连接的,也就是传输数据前需要先建立好连接,然后再进行传输。

  3. 双工通信

    TCP 连接一旦建立,就可以在连接上进行双向的通信。

  4. 可靠

    TCP 的传输是基于字节流,而不是报文。将数据按字节大小进行编号,接收端通过 ACK 来确认收到的数据编号。通过这种机制,TCP 协议能够保证接收数据的有序性和完整性。因此 TCP 能够提供可靠性传输。

  5. 流量控制

    TCP 还提供流量控制能力,通过滑动窗口来控制数据的发送速率。滑动窗口的本质是动态缓冲区,接收端根据自己的处理能力,在 TCP 的 Header 中动态调整窗口的大小,通过 ACK 应答包通知给发送端,发送端根据窗口的大小调整发送速率。

  6. 拥塞控制

    仅仅有了流量控制能力还不够,TCP 协议还考虑到了网络问题可能会导致大量重传,进而导致网络情况进一步恶化。因此 TCP 协议还提供了拥塞控制。TCP 处理拥塞控制主要是用到了慢启动、拥塞避免、拥塞发生、快速恢复四个算法。

除了 TCP 协议的特点,还可以进一步了解 TCP 协议的报文状态、滑动窗口的工作流程、keepAlive 的参数设置和 Nagel 算法的规则等一些细节。
另外还有典型的 TCP 协议问题,例如:特定场景下 Nagel 和 Ask 延迟机制配合使用,可能会出现延迟 40 毫秒超时后才能回复 ACK 包的问题。

TCP 协议的特点、三次握手建连、四次挥手断连_第1张图片

TCP 三次握手建连

  1. TCP 是基于连接的,所以在传输数据前需要先建立连接。

  2. TCP 在传输上是双工传输,不区分 Client 端与 Server 端。为了便于理解,我们把主动发起建连请求的一端称作 Client 端,把被动建立连接的一端称作 Server 端。

  3. 首先建立连接前需要 Server 端先监听端口,因此 Server 端建立连接前的初始状态就是 LISTEN 状态。

  4. 这时 Client 端,准备建立连接,先发送一个 SYN 同步包。发送完同步包后,Client 端的连接状态就变成了 SYN_SENT 的状态。

  5. Server 端收到 SYN 后同意建立连接,会向 Client 端回复一个 ACK。由于 TCP 是双工传输,Server 端同时也会向 Client 端发送一个同步请求 SYN,申请 Server 向 Client 方向建立连接,发送完 ACK 和 SYN 后,Server 端的连接状态就变成了 SYN_RCVD 状态。

  6. Client 端收到 Server 端的 ACK 后,Client 端的连接状态就变成了 ESTABLISHED 状态。同时 Client 端向 Server 端发送 ACK 响应,回复 Server 端的 SYN 请求。

  7. Server 端收到 Client 端的 ACK 后,Server 端的连接状态,也就变成了 ESTABLISHED 状态。

  8. 此时建连完成,双方随时可以进行数据传输。

在面试时需要明白三次握手是为了建立双向的连接,需要记住 Client 端和 Server 端的连接状态变化。
另外回答建连的问题时,可以提到 SYN 洪水攻击发生的原因,就是 Server 端收到 Client 端的 SYN 请求后发送了 ACK 和 SYN,但是 Client 端不进行回复,导致 Server 端大量的连接处在 SYN_RCVD 状态,进而影响其他正常请求的界面。
解决办法:
可以通过设置 Linux 的 TCP 参数 tcp_synack_retries=0,加快对于半连接的回收速度,或者调大 tcp_max_syn_backlog 来应对少量的 SYN 洪水攻击。

TCP 协议的特点、三次握手建连、四次挥手断连_第2张图片

TCP 四次挥手断连

  1. TCP 连接的关闭,通讯双方都可以先发起。我们暂且把先发起的一方看作 Client 端。

  2. 从图中可以看出,通信中的 Client 端和 Server 端的连接状态都是 ESTABLISHED 状态,然后 Client 端先发起了关闭连接的请求。Client 端向 Server端发送了一个 FIN 包,表示 Client 端已经没有数据要发送的了,然后 Client 端就进入了 FIN_WAIT_1 状态。

  3. Server 端收到 FIN 后回复 ACK,然后进入 CLOST_WAIT 状态。此时 Server 端属于半关闭状态,因为此时 Client 端向 Server 端方向已经不会再发送数据了,可是 Server 端向 Client 端可能还有数据要发送。

  4. Client 端在接收到 Server 端回复的 ACK 后变成 FIN_WAIT_2 状态。

  5. 当 Server 端数据发送完毕后,Server 端会向 Client 端发送 FIN 表示 Server 端也没有数据要发送。这时 Server 端进入 LAST_ACK 状态,等待 Client 端的应答就可以关闭连接了。

  6. Client 端收到 Server 端的 FIN 后回复 ACK,然后进入 TIME_WAIT 状态。TIME_WAIT 状态下需要等待两倍的 MSL(也就是最大报文段生存时间),来保证连接的可靠关闭。之后才会进入 CLOSED 状态。而 Server 端收到 ACK 后直接就可以进入 CLOSED 状态。

为什么需要等待两倍的 MSL 之后才能关闭连接?

原因有两个:
第一,要保证 TCP 协议的全双工连接能够可靠关闭;
第二,要保证这次连接中重复的数据段能够从网络中消失,防止端口被重用的时候可能会产生数据混淆。

为什么建连是三次握手,断连却要四次挥手?

从这个交互流程上可以看出,无论是建连还是断连,都是需要在两个方向上进行。
只不过建连时 Server 端的 SYN 和 ACK 两个包合并为一次发送,而断开连接时两个方向的数据发送的停止时间可能是不同的,所以无法合并 FIN 和 ACK 发送,这就是建连的时候必须要三次握手,而断连的时候必须要四次挥手的原因。

From:偶像-新浪微博资深技术专家 张雷

你可能感兴趣的:(计算机基础知识)