当前位置: 首页 > news >正文

TCP/UDP传输过程

一、TCP消息发送全流程(以网页加载为例)


场景模拟
  • 客户端:IP地址 192.168.1.100,浏览器访问 http://www.example.com
  • 服务器:IP地址 93.184.216.34(www.example.com),监听端口 80

详细步骤

1. 建立连接:三次握手

  • 步骤 1:客户端发送 SYN 包(主动打开)

    [以太网帧] 目标MAC: 路由器MAC | 源MAC: 客户端MAC
    [IP头部] 源IP: 192.168.1.100 | 目标IP: 93.184.216.34 | TTL: 64
    [TCP头部]
      - 源端口: 54321(随机临时端口)
      - 目标端口: 80
      - 序列号(seq): 1000(随机初始值)
      - 标志位: SYN=1(请求建立连接)
      - 窗口大小: 65535(初始接收窗口)
    

    物理层行为:客户端网卡将数据包发送到默认网关(路由器)。

  • 步骤 2:服务器回复 SYN-ACK 包

    [TCP头部]
      - 源端口: 80
      - 目标端口: 54321
      - 序列号(seq): 5000(服务器初始序列号)
      - 确认号(ack): 1001(客户端seq+1)
      - 标志位: SYN=1, ACK=1
      - 窗口大小: 8192
    

    服务器行为

    • 检查目标端口 80 是否有进程监听(如Nginx)。
    • 创建新的 TCP 连接控制块(TCB),记录客户端IP和端口。
    • 分配缓冲区,准备接收数据。
  • 步骤 3:客户端发送 ACK 包(连接建立完成)

    [TCP头部]
      - 标志位: ACK=1
      - 序列号(seq): 1001(初始seq+1)
      - 确认号(ack): 5001(服务器seq+1)
    

    客户端行为

    • 进入 ESTABLISHED 状态,开始发送应用数据。
    • 若未收到 SYN-ACK,重试 SYN 包(默认最多重试5次)。

2. 数据传输:HTTP请求与响应

  • 步骤 4:客户端发送 HTTP GET 请求

    [TCP头部]
      - 序列号(seq): 1001
      - 确认号(ack): 5001
      - 标志位: ACK=1, PSH=1(推送数据)
    [HTTP数据] 
      GET /index.html HTTP/1.1
      Host: www.example.com
      User-Agent: Chrome/120.0
    

    数据分片规则

    • 假设数据总长度 500字节,MSS(最大分段大小)为 1460字节,无需分片。
    • 若数据超过 MSS,TCP 层会分片(如 seq=1001:2461seq=2461:3921)。
  • 步骤 5:服务器确认数据接收(ACK)

    [TCP头部]
      - 序列号(seq): 5001
      - 确认号(ack): 1001 + 500 = 1501
      - 标志位: ACK=1
    

    服务器行为

    • 将数据存入接收缓冲区,通知应用层(Nginx)读取。
    • 若客户端未收到 ACK,在超时(如 200ms)后重传数据。
  • 步骤 6:服务器发送 HTTP 响应

    [TCP头部]
      - 序列号(seq): 5001
      - 确认号(ack): 1501
      - 标志位: ACK=1, PSH=1
    [HTTP数据]
      HTTP/1.1 200 OK
      Content-Length: 1300
      <html>...</html>
    

    数据分片示例

    • 若响应数据 1300字节,分为两段发送:
      • 第一段:seq=5001:6461(长度1460字节)
      • 第二段:seq=6461:6561(剩余100字节)。
  • 步骤 7:客户端确认响应数据

    [TCP头部]
      - 序列号(seq): 1501
      - 确认号(ack): 5001 + 1300 = 6301
      - 标志位: ACK=1
    

    客户端行为

    • 将数据重组后传递给浏览器渲染。
    • 若服务器未收到 ACK,重传最后一个数据段。

3. 关闭连接:四次挥手

  • 步骤 8:客户端发送 FIN 包(主动关闭)

    [TCP头部]
      - 序列号(seq): 1501
      - 确认号(ack): 6301
      - 标志位: FIN=1, ACK=1
    

    客户端状态转换ESTABLISHEDFIN_WAIT_1

  • 步骤 9:服务器回复 ACK 包

    [TCP头部]
      - 序列号(seq): 6301
      - 确认号(ack): 1502(客户端seq+1)
      - 标志位: ACK=1
    

    服务器状态转换ESTABLISHEDCLOSE_WAIT

  • 步骤 10:服务器发送 FIN 包(被动关闭)

    [TCP头部]
      - 序列号(seq): 6301
      - 确认号(ack): 1502
      - 标志位: FIN=1, ACK=1
    

    服务器状态转换CLOSE_WAITLAST_ACK

  • 步骤 11:客户端回复 ACK 包

    [TCP头部]
      - 序列号(seq): 1502
      - 确认号(ack): 6302(服务器seq+1)
      - 标志位: ACK=1
    

    客户端状态转换FIN_WAIT_2TIME_WAIT(等待2MSL,如60秒后关闭)


二、UDP消息发送全流程(以DNS查询为例)


场景模拟
  • 客户端:IP 192.168.1.100,查询 www.google.com 的IP地址
  • DNS服务器:IP 8.8.8.8(Google Public DNS),端口 53

详细步骤

1. 构造DNS查询报文

  • 应用层:生成DNS查询请求

    [DNS报文]
      - Transaction ID: 0x3a8f
      - Flags: 递归查询(RD=1)
      - Questions: 1(查询www.google.com的A记录)
    
  • 传输层:封装为UDP数据报

    [UDP头部]
      - 源端口: 49152(客户端随机临时端口)
      - 目标端口: 53
      - 长度: 8(UDP头) + 40(DNS数据) = 48字节
      - 校验和: 0x2e45(计算覆盖伪头部+UDP头+数据)
    [数据部分] DNS查询报文(40字节)
    
  • 网络层:封装为IP数据包

    [IP头部]
      - 源IP: 192.168.1.100
      - 目标IP: 8.8.8.8
      - 协议字段: 17(UDP)
      - TTL: 64
    
  • 链路层:封装为以太网帧

    [以太网帧]
      - 目标MAC: 默认网关MAC(如路由器)
      - 源MAC: 客户端网卡MAC
      - 类型: 0x0800(IPv4)
    

2. 发送数据包(无连接建立)

  • 客户端行为

    • 直接发送UDP数据包到 8.8.8.8:53
    • 不等待任何确认,继续执行其他任务。
  • 网络传输过程

    • 路由器根据目标IP 8.8.8.8 查找路由表,通过ISP转发。
    • 若中间路由器拥塞,可能直接丢弃数据包(UDP无重传机制)。

3. DNS服务器处理请求

  • 服务器接收

    [校验和验证]
      - 计算伪头部(源IP、目标IP、协议、UDP长度)+ UDP头 + 数据。  
      - 若校验和错误,静默丢弃数据包。
    

    服务器行为

    • 解析DNS查询,查找 www.google.com 的A记录(如 142.250.189.196)。
    • 构造响应报文:
      [DNS响应]
        - Transaction ID: 0x3a8f(与请求匹配)
        - Flags: 响应(QR=1),递归可用(RA=1)
        - Answer: 1条A记录(142.250.189.196)
      
  • 服务器发送响应

    [UDP数据报]
      - 源端口: 53
      - 目标端口: 49152
      - 长度: 8 + 60 = 68字节
      - 校验和: 0x5d21
    [IP头部]
      - 源IP: 8.8.8.8
      - 目标IP: 192.168.1.100
    

4. 客户端接收响应(或超时处理)

  • 成功接收

    • 客户端校验和验证通过后,提取 142.250.189.196,完成DNS解析。
  • 丢包场景

    • 若响应包丢失,客户端等待超时(如 5秒)后重发查询。
    • 示例重传
      第1次发送: T=0s → 未收到响应  
      第2次发送: T=5s → 仍未响应  
      第3次发送: T=10s → 成功接收  
      

三、TCP与UDP对比的关键细节

动作TCPUDP
连接建立需要三次握手,消耗1.5 RTT无握手,直接发送
数据传输可靠性每个包必须确认,超时重传无确认,不保证到达
数据顺序接收端按序列号排序可能乱序到达
头部开销20字节(基础)+ 可选字段固定8字节
流量控制通过窗口大小动态调整无控制,依赖应用层
拥塞控制慢启动、拥塞避免、快速重传无,可能加剧网络拥塞

四、技术细节补充

  1. TCP的序列号与确认号

    • 序列号:标识数据段的第一个字节的编号(如 seq=1001 表示数据从第1001字节开始)。
    • 确认号:期望收到的下一个字节编号(如 ack=1501 表示已正确接收前1500字节)。
  2. UDP校验和计算

    • 伪头部:包含源IP、目标IP、协议号(17)、UDP长度,用于防止路由错误。
    • 计算示例
      # 伪头部 + UDP头 + 数据
      pseudo_header = src_ip + dst_ip + protocol + udp_length
      checksum_data = pseudo_header + udp_header + payload
      # 按16位字求和,取反码
      
  3. TCP状态机

    • 客户端典型状态流
      CLOSED → SYN_SENT → ESTABLISHED → FIN_WAIT_1 → FIN_WAIT_2 → TIME_WAIT → CLOSED
    • 服务器典型状态流
      CLOSED → LISTEN → SYN_RCVD → ESTABLISHED → CLOSE_WAIT → LAST_ACK → CLOSED

五、实际抓包示例(Wireshark模拟)

TCP三次握手

No.  Time      Source           Destination      Protocol Info
1    0.000000 192.168.1.100    93.184.216.34    TCP      54321 → 80 [SYN] Seq=1000
2    0.102345 93.184.216.34    192.168.1.100    TCP      80 → 54321 [SYN, ACK] Seq=5000 Ack=1001
3    0.204678 192.168.1.100    93.184.216.34    TCP      54321 → 80 [ACK] Seq=1001 Ack=5001

UDP DNS查询

No.  Time      Source           Destination      Protocol Info
4    1.500000 192.168.1.100    8.8.8.8          UDP      49152 → 53 Len=48
5    1.602345 8.8.8.8          192.168.1.100    UDP      53 → 49152 Len=68

通过以上详细示例,可以清晰看到TCP如何通过握手、分段确认实现可靠传输,而UDP如何以极简方式实现快速通信。实际开发中需根据场景权衡选择协议。

相关文章:

  • 在 Spring Boot 中调用 AnythingLLM 的发消息接口
  • 如何确保爬虫遵守Shopee的使用条款?
  • uniapp实现全局拖拽按钮
  • 力扣算法Hot100——75. 颜色分类
  • GaussDB 资源管理指南:冻结、解冻、释放与生命周期控制
  • Node.js 中使用 RabbitMQ
  • 【Golang】go如何通过atomic原子操作来确保数据一致性
  • AFFiNE:下一代开源全能知识库工具,重新定义协作与创作
  • 深入理解JVM类加载机制:从原理到实践
  • 拓扑排序——117. 软件构建
  • 持续升级的电子实验记录本系统,更加好用、安全
  • 数据操作 + 数据预处理
  • JavaScript中的闭包:解锁函数的神秘力量
  • Linux--软硬链接、动静态库
  • Javascript 中事件环以及宏任务微任务详细介绍
  • VS2019 快捷键及各项功能汇总
  • 【GNN】0.环境配置
  • 【Pandas】pandas Index str
  • Quartus + VScode 实现模块化流水灯
  • 【Dive Into Stable Diffusion v3.5】1:开源项目正式发布——深入探索SDv3.5模型全参/LoRA/RLHF训练
  • 微软宣布全球裁员约3%:涉及约6000人,侧重经理层
  • 特朗普访问卡塔尔,两国签署多项合作协议
  • 佩斯科夫:俄方代表团15日将在伊斯坦布尔等候乌克兰代表团
  • 京东CEO许冉:外卖日单量接近2000万单,看到外卖对平台拉动和转化效应
  • 加拿大总理宣布新内阁名单
  • 检疫期缩减至30天!香港优化内地进口猫狗检疫安排