0%

TCP

1. 连接步骤

1.1. 建立连接

3 次握手

  1. Server 端建立连接前需要监听端口, 处于 LISTEN 状态.
  2. Client 端准备建立连接, 先发送一个 SYN 同步包给 Server 端, Client 端进入 SYN_SENT 状态.
  3. Server 端收到 SYN 后, 同意建立连接, 向 Client 端回复一个 ACK. 由于 TCP 是双工传输, Server 端也会同时向 Client 端发送一个 SYN, 申请 Server 向 Client 方向建立连接. 发送完 ACK 和 SYN 后, Server 端进入 SYN_RCVD 状态.
  4. Client 端收到 Server 端的 ACK 后, Client 端进入 ESTABLISHED 状态; 同时 Client 端 向 Server 端发送 ACK, 回复 Server 端的 SYN 请求.
  5. Server 端收到 Client 端的 ACK 后, Server 端也进入 ESTABLISHED 状态. 此时建连完成, 双方随时可以进行数据传输.

1.1.1. 为什么需要 3 次握手?

为了防止已失效的连接请求报文段突然又传送到了服务端导致错误.

在双方的 SYN 包中都会包含一个 随机序号, 在 ACK 应答时必须返回 随机序号 + 1.

1.1.2. 如何防御 SYN 洪水攻击?

SYN 洪水攻击的原因是 Server 端收到 Client 端的 SYN 请求后, 发送 ACK 和 SYN, 但是 Client 端不进行回复, 导致 Server 端大量的连接处于 SYN_RCVD 状态, 进而影响其他aggie请求的建连.

可以设置 tcp_synack_retries = 0 加快半连接的回收速度, 或者调大 tcp_max_syn_backlog 来应对大量的 SYN 洪水攻击.

1.2. 关闭连接

4 次挥手

  1. Client 端和 Server 端都是 ESTABLISHED 状态. 此时双方都可以发起关闭连接, 暂且把先发起的一方看做 Client 端.
  2. Client 端向 Server 端发送 FIN 包, 表示 Client 端已经没有数据要发送了, 然后 Client 端进入 FIN_WAIT_1 状态.
  3. Server 端收到 FIN 后, 返回 ACK, 然后进入 CLOSE_WAIT 状态, 而 Client 端接收到 ACK 后进入 FIN_WAIT_2 状态. 此时 Server 端属于半关闭状态, 因为此时 Client 端向 Server 端方向已经不会发送数据了, 可是 Server 端可能还有数据要发送.
  4. 当 Server 端发送完毕后, 向 Client 端发送 FIN, 表示 Server 端也没有数据发送了, 此时 Server 端进入 LAST_ACK 状态, 就等待 Client 端的应答就可以关闭连接了.
  5. Client 端收到 Server 端的 FIN 包后, 回复 ACK, 然后进入 TIME_WAIT 状态. Server 端接收到 ACK 后直接进入 CLOSED 状态. 而 Client 端在 TIME_WAIT 状态下需要等待 2 倍的最大报文段生存时间, 来保证连接的可靠关闭, 之后才会进入 CLOSED 状态.

1.2.1. 为什么 Client 端需要等待 2 倍的最大报文段生存时间之后才关闭连接?

  1. 保证 TCP 协议的全双工连接能够可靠关闭.
  2. 保证这次连接的重复数据段从网络中消失, 防止端口被重用时可能产生数据混淆.

1.2.2. 为什么需要 4 次挥手?

为了确认双方都没有数据发送.

2. 滑动窗口

// todo 2020-07-19

3. 拥塞控制

// todo 2020-07-19

4. Nagel 算法和 ACK 延迟

// todo 2020-07-19