自学教程 从零学编程

TCP 协议

一、TCP 是什么

TCP(Transmission Control Protocol,传输控制协议),属于 传输层协议,基于IP协议提供服务。
TCP是面向连接、可靠传输、全双工协议。HTTP、HTTPS、FTP、SSH 等绝大多数应用层协议底层都使用TCP。

面向连接:通信双方在传输数据前,必须先建立专属连接;通信结束后正常断开连接。
全双工:建立连接之后,双方可以同时收发数据。

二、TCP 核心特性

  1. 可靠传输
    通过序列号、确认应答、超时重传机制,保证数据能完整、有序、不重复地送达对方,不会丢失。
  2. 流量控制
    接收方缓冲区满的时候,可以通知发送方降低发送速率,防止发送方发太快,接收方来不及处理,造成数据丢失。核心依靠滑动窗口。
  3. 拥塞控制
    针对整个网络,当网络链路拥堵时,主动降低发送速度,避免加剧网络拥塞。常见算法:慢启动、拥塞避免、快重传、快恢复。
  4. 面向字节流
    TCP把应用层传来的数据看成一串连续的字节流,没有固定报文边界(没有消息边界),会出现粘包/拆包问题,需要应用层自己处理消息分割。

对比:UDP是无连接、不可靠、面向报文。

三、TCP 报文头部结构

TCP报文段,前面是TCP头部,后面承载应用层数据。
TCP头部默认最小20字节,可选选项最多40字节,头部最大60字节。

主要字段:

  • 源端口、目标端口:定位两端应用进程
  • 序列号(seq):本报文段数据第一个字节的编号
  • 确认号(ack):期望收到下一个字节的序列号,ack = 对方seq + 数据长度
  • 头部长度:TCP头部占多少字节
  • 6个标志位(Flags)
    • URG:紧急指针有效
    • ACK:确认号有效(连接建立后大部分报文ACK=1)
    • PSH:推送,接收方收到直接交给应用层,不缓存
    • RST:重置连接,强制断开
    • SYN:同步,用于建立连接
    • FIN:结束,用于关闭连接
  • 窗口大小:流量控制,接收方当前能接收的字节数量
  • 校验和:校验TCP头部+数据,检查传输是否出错
  • 紧急指针:配合URG标志,标记紧急数据位置

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

目的:同步双方序列号,协商初始序列号,确认收发能力正常。

前提:客户端主动发起连接请求,服务端端口处于监听(LISTEN)状态。

  1. 第一次握手(SYN)
    客户端发送 SYN=1,携带客户端初始序列号 seq=x。
    含义:客户端请求建立连接。客户端进入 SYN_SENT 状态。
  2. 第二次握手(SYN + ACK)
    服务端收到SYN报文,回复 SYN=1,ACK=1;
    ack = x+1;服务端自己的初始序列号 seq=y。
    含义:同意建立连接,确认收到客户端的请求。服务端进入 SYN_RCVD。
  3. 第三次握手(ACK)
    客户端收到SYN+ACK,回复 ACK=1;ack = y+1,seq=x+1。
    含义:客户端确认收到服务端的SYN。
    服务端收到这个ACK,双方状态都变为 ESTABLISHED,连接正式建立,可以传输业务数据。

一句话记忆:SYN,SYN+ACK,ACK
思考:为什么不是两次握手?两次握手无法确认客户端接收服务端报文的能力,存在安全与状态问题。

五、四次挥手(断开连接)

TCP连接是全双工,两个方向通道可以独立关闭,所以关闭连接需要四次交互。

  1. 第一次挥手(FIN)
    客户端发送 FIN=1,seq=u。客户端不再发送数据,进入 FIN_WAIT1。
    含义:客户端没有数据要发了,请求关闭客户端→服务端方向的通道。
  2. 第二次挥手(ACK)
    服务端回复 ACK=1,ack=u+1,seq=v。进入 CLOSE_WAIT。
    含义:收到关闭请求。此时服务端还可以继续向客户端发剩余数据。客户端收到ACK,进入 FIN_WAIT2。
  3. 第三次挥手(FIN)
    当服务端所有数据发送完毕,服务端发送 FIN=1,seq=w,ack=u+1。进入 LAST_ACK。
    含义:服务端也没有数据发送,请求关闭服务端→客户端通道。
  4. 第四次挥手(ACK)
    客户端收到FIN,回复 ACK=1,ack=w+1,seq=u+1。进入 TIME_WAIT。
    服务端收到ACK,直接进入 CLOSED,连接关闭。
    客户端等待 2MSL 时间之后,才进入 CLOSED。

一句话记忆:FIN,ACK,FIN,ACK
重点:TIME_WAIT 等待2MSL,一是保证对方收到最后ACK;二是等待网络残留报文失效,防止新建连接收到旧数据包。

六、可靠传输核心机制

  1. 序列号与确认应答(ACK)
    每个字节都有序号;接收方收到数据后返回ACK,告诉发送方已经收到哪部分数据。
  2. 超时重传
    发送报文后开启计时器;如果超时还没有收到ACK,就重新发送该报文,解决丢包问题。
  3. 校验和
    接收端校验,如果校验失败,直接丢弃报文,不回复ACK,触发对方超时重传。
  4. 去重
    利用序列号识别重复数据包,收到重复报文直接丢弃,保证数据只交付一次。
  5. 有序重组
    乱序到达的数据包,接收端根据序列号重新排序,再交给上层应用。

七、流量控制(滑动窗口)

接收方在ACK报文中带上自己的接收窗口大小。
发送方发送数据不能超过接收方窗口剩余容量,避免接收缓冲区溢出。窗口大小动态变化。
窗口单位:字节。

八、拥塞控制

流量控制解决收发两端之间速率匹配;拥塞控制解决整个网络链路拥堵问题。
核心四个阶段:慢启动 → 拥塞避免 → 快重传 → 快恢复。
发送方维护拥塞窗口 cwnd,根据网络情况动态调整发送上限。

九、TCP 粘包与拆包

TCP是字节流,没有边界。

  • 拆包:一个完整消息被拆分到多个TCP段传输;
  • 粘包:多个短消息被合并成一个TCP段一起发送。

TCP本身不感知业务消息边界,消息拆分逻辑需要应用层自己实现(固定长度、分隔符、消息头携带长度字段)。

十、小结

  1. TCP传输层协议,面向连接、可靠、全双工、字节流;
  2. 建立连接:三次握手;断开连接:四次挥手;
  3. 可靠依靠:序号、ACK、超时重传、校验;
  4. 滑动窗口做流量控制;拥塞窗口做拥塞控制;
  5. TCP无消息边界,存在粘包拆包,应用层处理。

思考题:TIME_WAIT为什么需要等待2MSL,能不能直接关闭?

标签:

0 条笔记