【Java EE】TCP(Transmission Control Protocol)

TCP 协议

  • [TCP 报头结构](#TCP 报头结构)
  • 可靠传输
  • 连接管理
  • 面向字节流
  • 滑动窗口
  • 流量控制和拥塞控制
  • 延时应答
  • 异常情况处理
  • [TCP 与 UDP 全面对比表⭐](#TCP 与 UDP 全面对比表⭐)
  • [如何基于 UDP 实现可靠传输⭐](#如何基于 UDP 实现可靠传输⭐)
    • [1. 分包与组包](#1. 分包与组包)
    • [2. 确认应答(ACK)](#2. 确认应答(ACK))
    • [3. 超时重传](#3. 超时重传)
    • [4. 乱序与去重处理](#4. 乱序与去重处理)
    • [5. 流量控制](#5. 流量控制)
    • [6. 拥塞控制](#6. 拥塞控制)
    • [7. 连接管理](#7. 连接管理)

TCP 报头结构

TCP 报头最小为 20 字节,最多可扩展至 60 字节,比 UDP 复杂得多,因为需要支持可靠性、流量控制、拥塞控制等机制。
至少20字节
源端口号

2字节
目的端口号

2字节
序列号

4字节
确认序列号

4字节
数据偏移+保留+标志位

2字节
窗口大小

2字节
校验和

2字节
紧急指针

2字节
选项字段

可选
应用层数据

各字段详细说明

字段 大小 说明
源端口号 2 字节 发送方端口号
目的端口号 2 字节 接收方端口号
序号 4 字节 本报文段数据的第一个字节的编号
确认号 4 字节 期望收到对方下一个报文段的第一个字节序号
数据偏移 4 位 TCP 报头长度 / 4(即有多少个 4 字节)
保留 3 位 全 0,保留未来用
标志位 9 位 控制连接状态(见下表)
窗口大小 2 字节 接收方还能接收多少字节(流量控制)
校验和 2 字节 检验报头 + 数据是否损坏
紧急指针 2 字节 URG=1 时有效,指明紧急数据末尾位置
可选项 0~40 字节 MSS、窗口缩放、时间戳等扩展功能

UDP 报头固定 8 字节,而 TCP 报头最小 20 字节,开销更大但功能更强。

9 个标志位详解

9 个标志位(9 bit)
NS
CWR
ECE
URG
ACK
PSH
RST
SYN
FIN

标志位 全称 作用
NS Nonce Sum ECN 防伪,极少使用
CWR Congestion Window Reduced 发送方告知"我已减小拥塞窗口"
ECE ECN-Echo 通知对方"我遇到了网络拥塞"
URG Urgent 紧急指针有效,数据需优先处理
ACK Acknowledgment 确认号字段有效(连接建立后始终置 1)
PSH Push 催促接收方立即提交应用层,不缓存
RST Reset 强制重置连接(异常终止)
SYN Synchronize 建立连接(三次握手的开始)
FIN Finish 释放连接(四次挥手的开始)

实际抓包中最常见的是:SYN、ACK、FIN、RST、PSH 五个。

可靠传输

【Java EE】TCP---可靠传输

连接管理

【Java EE】TCP---连接管理

面向字节流

【Java EE】TCP---面向字节流

滑动窗口

【Java EE】TCP---滑动窗口

流量控制和拥塞控制

【Java EE】TCP---流量控制和拥塞控制

延时应答

【Java EE】TCP---延时应答

异常情况处理

【Java EE】 TCP---异常情况处理

TCP 与 UDP 全面对比表⭐

特性 TCP UDP
连接模型 面向连接,需三次握手建立连接 无连接,直接发送数据
数据顺序 序列号保证,接收顺序与发送一致 无序,可能后发先至
可靠性 确认应答 + 超时重传 + 快速重传,保证数据到达 无确认,丢包即丢失,不重传
重复数据 接收缓冲区自动去重 可能重复,需应用层自行去重
流量控制 滑动窗口机制,防止发送方淹没接收方 无,可能丢包或接收方缓冲区溢出
拥塞控制 有多种拥塞控制算法(慢启动、拥塞避免、快速恢复等) 无,可能加剧网络拥塞
大包传输 自动分段,应用层无需关心 需应用层手动分包/组包(受 MTU 限制)
头部开销 最小 20 字节 固定 8 字节
端口 0~65535,服务器常用固定端口,客户端自动分配 同 TCP
校验和 强制校验(IPv4 可选项,但通常使用),更严格 可选校验,主要用于防比特翻转
编程复杂度 提供可靠字节流,编程简单,只需读写 若需可靠传输,必须自行实现拆包、组包、排序、确认、重传、去重、流量控制等
典型场景 文件传输、网页浏览、邮件等要求数据完整和顺序的场景 视频直播、语音通话、DNS 查询、局域网简单请求-响应等容忍少量丢包、追求低延迟的场景

如何基于 UDP 实现可靠传输⭐

UDP 本身只提供最基础的"端口到端口"数据报发送,不保证可靠性。要基于 UDP 实现可靠传输,必须在应用层补充以下机制:

1. 分包与组包

  • UDP 数据报大小受路径 MTU 限制,对于大块数据需要应用层负责拆分,并为每个分片添加序号分片标识(如首片、中间片、尾片)。
  • 接收方按序号重组,确认所有分片到齐后再交付上层。

2. 确认应答(ACK)

  • 发送方为每个数据包或每组分片分配唯一序号。
  • 接收方收到数据后,回复 ACK 报文,携带已成功接收的最大连续序号或位图(SACK,选择性确认),以通知发送方哪些包已到达。
  • 发送方根据 ACK 判断是否需要重传。

3. 超时重传

  • 发送方在发送数据后启动定时器,若超时未收到对应 ACK,则重传该数据包。
  • 超时时间(RTO)需要根据网络往返时间(RTT)动态估算,避免过早或过晚重传。

4. 乱序与去重处理

  • 接收方根据序号对数据包排序,使交付给上层的数据流保持原始顺序。
  • 接收方需维护已接收序号集合,对重复到达的数据包直接丢弃,避免重复递交。

5. 流量控制

  • 接收方在 ACK 中通告自身的接收窗口(缓冲区剩余大小),限制发送方在未确认情况下的最大发送量,防止接收方被淹没。
  • 发送方根据通告窗口调整发送速率。

6. 拥塞控制

  • 实现类似 TCP 的拥塞控制算法(如慢启动、拥塞避免、快速重传与恢复),根据丢包和延迟变化调整发送速率,避免过度占用网络导致拥塞崩溃。
  • 典型的基于 UDP 的可靠协议(如 QUIC)都内置了拥塞控制模块。

7. 连接管理

  • 虽然 UDP 无连接,但可靠传输通常需要维护会话状态。可通过握手(如 Hello/HelloAck)建立连接,通过关闭消息或超时来拆除连接,以便管理资源、初始化序号等。

综合来看,实现一个完整的可靠 UDP 协议工作量巨大,实际上相当于重新实现一个类 TCP 的传输层,现代做法通常直接采用已成熟的 QUIC 等协议,而不是从零开始。

相关推荐
TechWayfarer4 小时前
街道级IP定位的技术边界:IP精准定位服务在本地生活场景的落地实践
大数据·网络·python·tcp/ip·生活
少年攻城狮4 小时前
阿里云系列---【申请域名并绑定到主机ip】
linux·服务器·tcp/ip·阿里云·云计算
XiYang-DING4 小时前
【Java EE】TCP—连接管理
网络·tcp/ip·java-ee
周末也要写八哥4 小时前
TCP三次握手与四次挥手的过程
java·网络·tcp/ip
中科三方4 小时前
域名解析修改后,用户仍访问旧IP?原因排查与高效解决指南
网络协议·tcp/ip·php
辣椒思密达4 小时前
大规模数据采集如何稳定使用海外住宅IP?3种实战方法
网络·网络协议·tcp/ip
xiaoshuaishuai84 小时前
C# Anthropic连接超时原因及方案
开发语言·网络·tcp/ip·c#
bubiyoushang8884 小时前
STM32L051 的 串口升级
stm32·单片机·嵌入式硬件
210Brian4 小时前
蓝桥杯单片机学习笔记(十二):V2026 大模板构建(上)
单片机·学习·蓝桥杯