TCP知识总结

116 阅读6分钟

tcp是可靠的,tcp向另外一端发送数据时候,它要求对端返回一个确认,如果没有收到确认,它将自动重传。

tcp会动态估算客户端和服务器的往返时间RTT,以便知道等待一个确认大概需要多久。

tcp给每个字节关联一个序号,对所发送数据进行排序。这样可以去重

tcp流量控制,告知对端它能够接受的数据有多少,确保缓冲区不会溢出。

tcp是全双工的。

tcp三次握手

TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的传输层协议,其连接的建立和终止分别通过三次握手四次挥手实现。这两个过程是保证 TCP 可靠性的基础,下面详细介绍:

一、三次握手(建立连接)

三次握手(Three-Way Handshake)是客户端和服务器建立 TCP 连接的过程,目的是确认双方的发送和接收能力,并协商初始序列号(ISN)。

过程详解:
  1. 第一次握手(客户端 → 服务器)

    • 客户端主动发起连接,发送一个 SYN(Synchronize Sequence Number,同步序列编号)  报文段。
    • 报文中包含:SYN=1(标志位)、客户端的初始序列号 seq = x(随机生成的 32 位整数)。
    • 此时客户端状态从 CLOSED 变为 SYN-SENT
  2. 第二次握手(服务器 → 客户端)

    • 服务器收到 SYN 报文后,确认可以建立连接,回复一个 SYN+ACK(同步 + 确认)  报文段。
    • 报文中包含:SYN=1ACK=1(标志位)、服务器的初始序列号 seq = y、确认号 ack = x + 1(表示已收到客户端的 x 序号,期望下次接收 x+1)。
    • 此时服务器状态从 LISTEN 变为 SYN-RCVD
  3. 第三次握手(客户端 → 服务器)

    • 客户端收到 SYN+ACK 报文后,发送一个 ACK(Acknowledgment,确认)  报文段。
    • 报文中包含:ACK=1(标志位)、序列号 seq = x + 1、确认号 ack = y + 1(表示已收到服务器的 y 序号,期望下次接收 y+1)。
    • 此时客户端状态从 SYN-SENT 变为 ESTABLISHED;服务器收到 ACK 后,状态从 SYN-RCVD 变为 ESTABLISHED,连接正式建立。
为什么需要三次握手?
  • 核心目的:防止「已失效的连接请求报文段」被服务器接收,导致错误。
    例如:客户端发送的第一个 SYN 报文因网络延迟滞留,客户端超时后重新发送并建立连接;若滞留的 SYN 报文随后到达服务器,服务器会误以为是新连接并回复 SYN+ACK,此时客户端通过第三次握手的 ACK 确认,服务器可识别这是无效连接并拒绝,避免资源浪费。
  • 三次握手也能确保双方的发送和接收缓冲区、序列号等参数协商一致。

二、四次挥手(终止连接)

四次挥手(Four-Way Wavehand)是 TCP 连接终止的过程,由于 TCP 是全双工通信(双方可同时发送数据),需要双方分别确认关闭各自的发送通道。

过程详解:
  1. 第一次挥手(主动关闭方 → 被动关闭方)

    • 假设客户端主动关闭连接,发送一个 FIN(Finish,结束)  报文段。
    • 报文中包含:FIN=1(标志位)、序列号 seq = u(客户端当前的发送序号)。
    • 此时客户端状态从 ESTABLISHED 变为 FIN-WAIT-1,表示客户端不再发送数据,但仍可接收数据。
  2. 第二次挥手(被动关闭方 → 主动关闭方)

    • 服务器收到 FIN 后,回复一个 ACK 报文段,确认客户端的关闭请求。
    • 报文中包含:ACK=1、序列号 seq = v、确认号 ack = u + 1
    • 此时服务器状态从 ESTABLISHED 变为 CLOSE-WAIT,客户端收到 ACK 后状态变为 FIN-WAIT-2
    • 注意:此时服务器可能还有未发送完的数据,会继续向客户端发送。
  3. 第三次挥手(被动关闭方 → 主动关闭方)

    • 服务器发送完所有数据后,也发送一个 FIN 报文段,告知客户端可以关闭接收通道。
    • 报文中包含:FIN=1ACK=1、序列号 seq = w、确认号 ack = u + 1(与第二次挥手的 ack 一致,因服务器未收到新数据)。
    • 此时服务器状态从 CLOSE-WAIT 变为 LAST-ACK
  4. 第四次挥手(主动关闭方 → 被动关闭方)

    • 客户端收到 FIN 后,回复一个 ACK 报文段,确认服务器的关闭请求。
    • 报文中包含:ACK=1、序列号 seq = u + 1、确认号 ack = w + 1
    • 此时客户端状态从 FIN-WAIT-2 变为 TIME-WAIT(等待 2 个 MSL 时间,确保服务器收到 ACK),服务器收到 ACK 后状态变为 CLOSED
    • 客户端等待 2MSL 后,状态变为 CLOSED,连接彻底终止。
为什么需要四次挥手?
  • 全双工通信的必然结果:TCP 连接的两端都有发送和接收缓冲区,关闭连接时需分别确认双方的发送通道已关闭。

    • 主动关闭方发送 FIN 表示 “我不再发数据”,被动关闭方先回复 ACK 确认 “收到你的关闭请求”,但可能还在发送数据,因此需等待数据发送完毕后再发送自己的 FIN,表示 “我也不再发数据”,最后由主动关闭方确认。
  • TIME-WAIT 状态的意义:防止最后一个 ACK 丢失导致服务器重发 FIN,确保连接终止的可靠性;同时等待网络中残留的报文段过期,避免干扰新连接。

总结

  • 三次握手:通过三次交互确认双方收发能力,建立可靠连接,核心是 “同步序列号” 和 “防止无效连接”。
  • 四次挥手:通过四次交互分别关闭双方的发送通道,因全双工特性需各自确认,核心是 “双向关闭” 和 “确保数据传输完毕”。

这两个过程是 TCP 可靠性的基础,也是理解网络编程中连接管理(如超时重连、断连检测)的关键。

三、类比理解:像 “打电话确认”,少一步就会出错

可以用日常生活中的 “双向确认” 类比:

  • 你(客户端)给朋友(服务器)打电话,说 “喂,能听到吗?”(第一次 SYN);
  • 朋友说 “能听到!你能听到我吗?”(第二次 SYN+ACK);
  • 你必须说 “能听到!”(第三次 ACK),朋友才会开始说话 —— 如果少了这一步,朋友不知道你是否能听到他,贸然开始说话,你可能根本没收到,沟通就会失效。

TCP 的三次握手,本质就是完成 “你能听我、我能听你” 的双向确认,少一步都无法保证后续通信的可靠性