一、 TFTP 协议(简单文件传输协议)

核心特征:基于UDP实现,端口号69,适用于简单的文件传输场景。

1.协议的报文格式

TFTP的报文主要由操作码数据内容组成,各字段之间通常用0x00字节分隔

  • 读写请求报文 (RRQ/WRQ)

    • 操作码:2 字节
      • 0x0001:读请求 (RRQ)
      • 0x0002:写请求 (WRQ)
    • 文件名:可变长度(ASCII 字符串)
    • 0x00:分隔符
    • 模式:字符串(如 "netascii", "octet")
    • 0x00:分隔符
  • 数据报文 (DATA)

    • 操作码:2 字节 (0x0003)
    • 块编号:2 字节(用于标识数据块顺序,从 1 开始)
    • 数据:0 ~ 512 字节
      • *注:若数据段长度 < 512 字节,表示这是最后一个数据包。
  • 确认报文 (ACK)

    • 操作码:2 字节 (0x0004)
    • 块编号:2 字节(确认收到的块号)
  • 错误报文 (ERROR)

    • 操作码:2 字节 (0x0005)
    • 差错码:2 字节(如 1=文件未找到,2=访问违规等)
    • 差错信息:ASCII 字符串
    • 0x00:结束符

2.通讯流程(上传/下载)

1.发起:客户端发送RRQ(下载)或WRQ(上传)。

2.传输:

下载:服务器发送DATA((1)->客户端发送ACK(1)->服务器发送DATA(2)...

上传:客户端发送DATA(1)->服务器发送Ack(1)->客户端发送DATA(2)...

3.结束:当一方发送的数据小于512字节时,另一方回复ACK后,连接断开。

二、 TCP/IP 协议与网络封包

1.网络封包格式

  • TCP 首部 (20字节固定部分)

    • 源/目的端口:16 bit,标识通信的进程。
    • 序号 (Sequence Number):32 bit,当前数据第一个字节的序号。
    • 确认号 (Acknowledgment Number):32 bit,期望收到对方的下一个序号。
    • 数据偏移:4 bit,指示 TCP 首部长度(以 4 字节为单位)。
    • 控制位 (Flags)
      • SYN:同步序号,用于建立连接。
      • ACK:确认序号有效。
      • FIN:发送完数据,请求断开。
      • PSH:推送接收方立即交付给应用层。
      • RST:重置连接。
      • URG:紧急指针有效。
    • 窗口 (Window):16 bit,用于流量控制,告知对方还能接收多少字节。
  • IP 首部 (20字节固定部分)

    • 版本号:IPv4 或 IPv6。
    • 首部长度:同 TCP 数据偏移。
    • 总长度:整个 IP 数据报的长度。
    • 标识、标志位、片偏移:用于分片与重组。
    • TTL (Time to Live):生存时间,防止数据包在网络中无限循环。
    • 协议:8 bit,指明上层协议类型(如 6=TCP, 17=UDP)。

2. 数据封装过程
数据在发送端自上而下封装:

  1. 应用层:原始数据。
  2. 传输层:加上 TCP/UDP 首部 -> 报文段 (Segment)
  3. 网络层:加上 IP 首部 -> 数据报 (Datagram)
  4. 链路层:加上 MAC 首部和尾部 (FCS) -> 帧 (Frame)
  5. 物理层:转换为比特流传输。

3. TCP “粘包”问题

  • 原因
    • 本质:TCP 是面向字节流的协议,没有消息边界概念。
    • 发送方:Nagle 算法为了减少小包发送,可能会将多次写入的数据合并。
    • 接收方:应用层读取数据的粒度与内核缓冲区的数据量不匹配。
    • 网络层:IP 层的分片与重组也可能影响。
  • 解决方案
    • 定长法:规定每个包固定长度,不足补空。
    • 特殊分隔符:如 HTTP 使用 \r\n\r\n
    • 长度前缀法:在数据前加上数据长度(最常用)
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐