以太网数据帧详解
1. 以太网数据帧(链路层)
通信过程中,每层协议都要加上一个数据首部(header),称为封装(Encapsulation)。
不同协议层对数据包称为不同,传输层称为段(segment),网络层称为数据报(datagram),链路层称为帧(frame)。如 UDP 段、IP 数据报和以太网帧。
数据封装成帧后发到传输介质上,到达目的主机后每层协议再剥掉相应的首部,最后将应用层数据交给应用程序处理。
以太网帧的完整结构
字段 | 长度 | 说明 |
---|---|---|
目标MAC地址 | 6字节 | 接收方的MAC地址 |
源MAC地址 | 6字节 | 发送方的MAC地址 |
类型字段 | 2字节 | 表示帧中数据的协议类型 |
数据部分(包括帧的有效载荷) | 46字节 - 1500字节 | 携带上层协议的数据,数据长度至少46字节,最多1500字节 |
FCS(帧校验序列) | 4字节 | 用于错误检测的CRC校验值 |


1.2 以太网首部
以太网帧头占用 14 Bytes,通常由以下几个部分组成:
-
目标MAC地址(Destination MAC Address):6 Bytes
-
源MAC地址(Source MAC Address):6 Bytes
-
类型/长度字段(Type/Length Field):2 Bytes

1.2.1 目标MAC地址(Destination MAC Address)
这是接收端设备的MAC地址,表示该帧是发往哪个设备的。以太网中,每个网络接口都有一个唯一的MAC地址,用于标识设备。在数据包传输过程中,目标MAC地址指示了帧的接收方。
- 单播(Unicast):目标MAC地址是唯一的,指定了一个单一的接收设备。
- 广播(Broadcast):目标MAC地址是
FF:FF:FF:FF:FF:FF
,表示该数据包是发往网络上所有设备的。 - 组播(Multicast):目标MAC地址是特定的一组地址,表示该帧是发给一个特定组的多个设备。
1.2.2 源MAC地址(Source MAC Address)
这是发送端设备的MAC地址,表示数据帧的来源。每个网络接口卡(NIC)都有一个唯一的MAC地址,用于标识该设备。源MAC地址标明了该数据帧的发送者。
1.2.3 类型/长度字段(Type/Length Field)
在传统的以太网帧格式中,类型字段有两种用途,具体是取决于以太网的帧类型。这里我们按以太网II格式来解释,因为它是最常见的标准。
- 类型字段(Ethernet II帧格式):
- 长度:2字节(16位)
- 描述:类型字段表示数据部分所使用的上层协议。例如:
- 0x0800:IPv4协议
- 0x0806:ARP协议
- 0x86DD:IPv6协议
- 0x8847、0x8848:用于IEEE 802.1Q VLAN标签。
通过类型字段,接收设备能够知道帧中的数据部分属于哪个上层协议,进而传递到正确的协议栈进行进一步处理。
- 长度字段(IEEE 802.3帧格式):
- 在IEEE 802.3标准中,这个字段表示后续数据部分的长度,而不是协议类型。在这种情况下,长度字段的值指明数据部分的字节数(不包括帧头和FCS字段)。但是,现代以太网中几乎所有应用都使用以太网II类型格式。
1.3 FCS(Frame Check Sequence)
FCS(Frame Check Sequence),即“帧校验序列”,是以太网帧的最后一个字段,用于数据的错误检测。它的作用是确保数据在传输过程中没有受到损坏,能有效地检测并防止错误数据被接收和处理。FCS字段是通过CRC(循环冗余校验)算法生成的,它依赖于帧中的所有数据字段(包括头部、数据部分等),并计算出一个校验值。
FCS字段的格式
- FCS长度:4字节(32位)
- FCS内容:由发送端通过CRC算法生成的32位校验码
2. IP 数据报(网络层)
IP 数据报(IP Datagram) 是传输层协议(如TCP或UDP)与链路层协议(如以太网)之间的数据单位。它是互联网协议(IP) 中定义的基本数据单元,用于在网络中传输信息。IP 数据报携带了用于定位源和目标设备的地址信息,以及一些控制和错误处理信息。
IP 数据报的结构分为 IP 头和数据部分,其中 IP 头用于存放协议相关的元数据,而数据部分则携带上层协议的有效载荷(如 TCP
数据、UDP
数据等)。根据 IP 版本的不同,数据报的结构也有所差异,常见的版本是 IPv4
和 IPv6
。下面,我们以 IPv4
数据报为例详细解释其结构。
2.1 IP 首部
IPv4
头部的大小是 20字节,但它的长度可以根据 选项字段(Options) 有所变化。IPv4
头部包含了许多不同的字段,下面是详细的字段解析:
字段名称 | 长度 (比特) | 说明 |
---|---|---|
版本(Version) | 4 | 指定IP协议的版本,IPv4时值为4。 |
头部长度(IHL) | 4 | 指定IP头部的长度,单位为4字节。IPv4的最小头部长度是5(即20字节)。 |
服务类型(Type of Service, ToS) | 8 | 定义数据报的优先级和服务质量(QoS)。 |
总长度(Total Length) | 16 | 数据报的总长度,单位是字节,包含头部和数据部分。 |
标识(Identification) | 16 | 用于数据报分片时,标识属于同一数据报的各个片段。 |
标志(Flags) | 3 | 控制分片的标志位,指定是否允许分片,是否是最后一个片段等。 |
片偏移(Fragment Offset) | 13 | 指示当前片段在原始数据报中的位置,用于分片和重组。 |
生存时间(TTL, Time to Live) | 8 | 限制数据报在网络中的生命周期(即最大跳数),防止数据报在网络中无限循环。 |
协议(Protocol) | 8 | 指定数据部分使用的上层协议类型,例如:TCP(6),UDP(17),ICMP(1)。 |
头部校验和(Header Checksum) | 16 | 用于检查头部是否在传输过程中被损坏。 |
源IP地址(Source IP Address) | 32 | 源主机的IP地址。 |
目标IP地址(Destination IP Address) | 32 | 目标主机的IP地址。 |
选项(Options) | 可变 | 可选字段,用于指定额外的控制信息,常用于路由、时间戳等。 |
填充(Padding) | 可变 | 用于填充选项字段的大小,使头部长度是4字节的倍数。 |

2.2 数据部分(Data)
数据部分包含了上层协议的有效载荷。对于 IPv4 数据报来说,数据部分是协议栈中的传输层协议(如TCP、UDP)或其他协议的内容。例如:
- 如果是 TCP 数据包,数据部分就是 TCP 头部和数据。
- 如果是 UDP 数据包,数据部分就是 UDP 头部和数据。
数据部分的最大长度由总长度字段决定(最大为 65535 字节),减去头部的长度(通常为 20 字节),即最大数据部分为 65515 字节。
3. TCP段(传输层)
TCP 段(TCP Segment)是传输控制协议(TCP)在网络中进行通信的基本数据单元。TCP 是一个面向连接的协议,它通过端到端的可靠通信来确保数据完整无误地传输。因此,TCP 段不仅承载应用层数据,还包含了确保数据传输可靠性的控制信息。
它由 TCP 头部和数据部分组成。
- TCP 首部:包含控制信息,用于数据的路由、可靠性、流量控制、错误检测等。
- 数据部分:承载实际的应用层数据(如 HTTP 请求、文件传输数据等)。
3.1 TCP 首部
TCP 首部部的最小长度为 20 字节,但如果包含选项(Options),则长度会增加。TCP 首部的字段如下:
字段名称 | 长度(比特) | 说明 |
---|---|---|
源端口号(Source Port) | 16 | 源主机的端口号,表示发送端的应用程序。 |
目标端口号(Destination Port) | 16 | 目标主机的端口号,表示接收端的应用程序。 |
序列号(Sequence Number) | 32 | 数据字节流中的第一个字节的序列号,用于跟踪已发送的数据。 |
确认号(Acknowledgment Number) | 32 | 表示期望收到的下一个字节的序列号,用于确认接收到的数据。 |
数据偏移(Data Offset) | 4 | 表示TCP头部的长度,单位为4字节,表示从TCP段开始到数据部分的偏移。 |
保留(Reserved) | 3 | 保留字段,通常为0,用于以后的协议扩展。 |
控制位(Flags) | 9 | 该字段包含了用于控制连接的标志位,常见的标志位包括: |
- URG(紧急指针有效): 如果为1,表示数据中包含紧急数据。 | ||
- ACK(确认号有效): 如果为1,表示确认号字段有效。 | ||
- PSH(推送标志): 如果为1,表示接收方应立即将数据交给应用程序。 | ||
- RST(重置连接): 如果为1,表示重新建立连接。 | ||
- SYN(同步连接): 如果为1,表示用于建立连接。 | ||
- FIN(连接终止): 如果为1,表示发送方已经完成数据传输。 | ||
窗口大小(Window Size) | 16 | 表示接收端的接收窗口大小,用于流量控制。 |
校验和(Checksum) | 16 | 用于错误检测,确保TCP头部和数据部分在传输过程中没有发生错误。 |
紧急指针(Urgent Pointer) | 16 | 如果URG标志位为1,紧急指针字段表示数据中紧急部分的最后一个字节位置。 |
选项(Options) | 可变 | 额外的可选字段,通常用于最大报文段长度(MSS)、时间戳等。 |
填充(Padding) | 可变 | 用于使TCP头的长度是4字节的倍数。 |

-
源端口号和目标端口号(Source Port and Destination Port)
每个 TCP 段都有一个源端口号和目标端口号,它们用于确定发送方和接收方的应用程序。这两个端口号一起构成了 TCP 连接的唯一标识符(即四元组:源IP地址、源端口、目标IP地址、目标端口)。 -
序列号(Sequence Number)
- 序列号用于标识发送的字节流中的每个字节。序列号确保数据按照正确的顺序重组,即使数据包顺序被打乱,接收方也能正确还原。
- 当建立连接时,TCP 会初始化一个序列号,后续每发送一个字节,序列号就会递增。
- 确认号(Acknowledgment Number)
- 确认号是接收方期望下一个字节的序列号。它用于告诉发送方哪些字节已成功接收,并确认数据的接收。
- 如果接收方收到一个 TCP 段,它会将该段的最后一个字节序列号 +1 作为确认号发送回发送方。
-
数据偏移(Data Offset)
数据偏移字段指定 TCP 头部的长度。它告诉接收方从哪个位置开始读取数据部分。由于 TCP 头部可能有选项字段,因此头部长度是可变的。 -
控制位(Flags)
- 控制位(9个标志位)用于控制 TCP 连接的建立、维护和终止。主要的标志位包括:
- SYN(同步连接):用于连接建立时的握手过程。
- ACK(确认号有效):表示确认号有效。
- FIN(连接终止):表示发送方没有数据发送,连接可以终止。
- RST(重置连接):表示连接异常,需要重新初始化连接。
- PSH(推送标志):表示接收方应立即将数据传递给应用程序,不需缓冲。
- URG(紧急指针有效):表示数据段中包含紧急数据。
-
窗口大小(Window Size)
窗口大小用于流量控制,表示接收端的接收缓存区能够接收的数据量。它告知发送方,接收方当前能够接收多少字节的数据。
-
校验和(Checksum)
校验和用于检测在传输过程中是否发生了数据错误。它是对 TCP 头部和数据部分一起计算的,接收方可以通过校验和来判断数据是否在传输过程中发生了错误。
-
紧急指针(Urgent Pointer)
紧急指针字段只有在 URG 标志为1时有效。它指示数据部分中的紧急数据的结束位置。当 URG 标志为1时,接收方会优先处理紧急数据。
-
选项(Options)
- 选项字段用于提供额外的控制信息。常见的选项有:
- 最大报文段长度(MSS, Maximum Segment Size):表示发送方和接收方能够处理的最大 TCP 段大小。
- 时间戳:用于计算往返时间(RTT)和进行其他性能优化。
- 窗口扩大因子(Window Scale):用于 TCP 窗口大小的扩展,允许在高速网络中使用更大的窗口大小。
-
填充(Padding)
为了确保 TCP 头部的长度是 4 字节的倍数,填充字段会被使用。填充不会对数据传输产生影响,它只是确保头部长度符合规定。
3.2 数据部分
数据部分 包含了上层协议(如 HTTP、FTP 等)传递给 TCP 的实际数据。数据部分的长度可以根据 TCP 段的总长度和头部长度的差值来确定。每个 TCP 段最多承载 64KB 的数据(理论上),但实际数据大小通常会受到 MSS(最大报文段大小)的限制。
每个应用层协议通过 TCP 进行数据传输时,都会将自己的数据作为 TCP 段的有效载荷。典型的应用层数据包括:
- HTTP 请求/响应消息体
- 文件传输数据
- DNS 请求/响应数据
- SMTP 邮件数据等
3.3 TCP 段的数据传输过程
- 应用数据:应用程序(如 Web 浏览器、邮件客户端等)首先会生成需要传输的数据。比如,当你访问网页时,浏览器生成一个 HTTP 请求,并将其交给 TCP 协议栈进行传输。
- 分段:TCP 根据应用数据的大小以及网络的 MTU(最大传输单元)对数据进行分段。每个分段就会形成一个独立的TCP 段,数据部分就是这些分段的有效载荷。
- 封装:TCP 协议会将应用数据封装到数据部分,并附加相应的头部信息(如序列号、确认号、校验和等)形成完整的TCP 段。
- 传输:这个 TCP 段被发送到网络中,数据部分将由网络中的其他设备(如路由器、交换机)进行转发,直到到达目标设备。
- 接收与重组:接收方根据 TCP 的控制信息(如序列号和确认号)将所有收到的 TCP 段的数据部分拼接成完整的应用数据,并将其传递给上层应用程序。
3.4 TCP 段的分片与重组
- 分片:如果一个 TCP 段的大小超出了网络的最大传输单元(MTU),它将被分割成多个较小的片段,每个片段都会带有一个序列号和确认号,以便接收端能够正确地重新组装。
- 重组:接收端根据 TCP 段中的序列号和确认号将分片的数据段重组回原始的完整数据。
4. UDP 段(传输层)
UDP(用户数据报协议) 是一个无连接的传输层协议,它在网络通信中提供的是一种尽力而为的服务。与 TCP 不同,UDP 不提供保证可靠性、顺序控制或流量控制等特性,而是以更简单的方式进行数据传输。因此,UDP 协议的首部相对较为简单。
4.1 UDP 首部
UDP首部包含了最基本的控制信息,只有4个固定字段,每个字段的长度固定且较小。UDP协议的首部没有像TCP那样复杂的控制信息,例如没有序列号、确认号、窗口大小等字段。下面是UDP首部的结构及字段说明:
字段名称 | 长度(比特) | 说明 |
---|---|---|
源端口号(Source Port) | 16 | 发送方的端口号。 |
目标端口号(Destination Port) | 16 | 接收方的端口号。 |
长度(Length) | 16 | UDP段的总长度,包括头部和数据部分的总长度。 |
校验和(Checksum) | 16 | 用于错误检测,确保UDP段在传输过程中没有发生错误。 |

- 源端口号(Source Port):16比特
- 源端口号字段用于标识数据源的端口(发送方的端口)。
- 如果发送方没有特定的源端口要求,这个字段可以设置为0(例如,在某些情况下,DNS 查询的 UDP 源端口就是0)。
- 该字段帮助接收方知道该数据包是从哪个端口发来的。
- 目标端口号(Destination Port):16比特
- 目标端口号字段标识接收方的端口,即数据接收的目的端口。
- UDP 通过目标端口号来将数据发送到正确的应用程序或服务上。例如,HTTP 协议通常使用端口 80,DNS 通常使用端口 53 等。
- 长度(Length):16比特
- 长度 字段表示整个 UDP 段的长度(以字节为单位),包括 UDP 首部 和 数据部分 的总长度。
- 最小长度是 8 字节(仅包含头部部分)。因此,UDP 数据部分的最小长度是 0 字节,最大长度可以为 65535字节(16位无符号整数的最大值)。实际上,数据部分的大小通常由网络层的最大传输单元(MTU)来决定。
- 这个字段允许接收方了解 UDP 段的实际大小,从而能够正确地解析数据。
- 校验和(Checksum):16比特
- 校验和字段用于检测 UDP 段在传输过程中是否发生了错误。
- 校验和是对整个 UDP 段(包括 UDP 头部和数据部分)的计算值,用于保证数据的完整性。
- 如果接收到的数据段的校验和不匹配,接收方会丢弃该段,并根据协议的设计选择是否请求重发。需要注意的是,校验和是可选的,尤其是在
IPv4
中,如果 UDP 段的源和目标地址都使用的是本地网络,校验和字段可以设置为 0;但在IPv6
中,UDP 校验和是必选项。
4.2 数据部分
UDP 的数据部分承载的内容取决于应用层协议。它就是从 UDP 头部后开始到 UDP 段的末尾的所有字节。因此,UDP 的有效载荷可以是任何应用层协议的数据,如 HTTP 请求、视频流、DNS 查询响应等。
例如:
- DNS:DNS请求和响应的UDP数据部分通常包含域名解析请求的内容(如要查询的域名、查询类型等),或者DNS服务器返回的IP地址列表。
- 视频流:视频应用程序(如实时视频流或语音通话)将视频或音频数据作为UDP数据部分传输。
- 简单数据传输:例如一个应用程序将一小段文本数据通过UDP传输,那么数据部分将包含该文本数据。
5. 五元组(Five-Tuple)
五元组(Five-Tuple)是网络中用来唯一标识一条TCP连接的五个核心要素,通常用于描述一条端到端的连接。五元组包括以下五个字段:
- 源IP地址(Source IP Address)
- 源端口号(Source Port)
- 目标IP地址(Destination IP Address)
- 目标端口号(Destination Port)
- 协议类型(Protocol)
这些字段组合在一起,就可以唯一标识在网络中进行通信的两个端点之间的连接。
测试实例
机器名 | mac地址 | ip地址 | 端口 |
---|---|---|---|
server | 00:0c:29:8b:37:da | 10.1.2.7 | 9502 |
client | 00:50:56:c0:00:08 | 10.1.2.1 | 12345 |
客户端向服务端发送 hello world
,抓包结果:
# 原始数据帧
00 0c 29 8b 37 da 00 50 56 c0 00 08 08 00 # Ethernet_II格式数据帧首部
45 00 00 33 28 5b 40 00 80 06 ba 80 0a 01 02 01 0a 01 02 07 # ip协议头
30 39 25 1e 84 a4 e6 82 cf f2 ea 28 50 18 10 0a 7b 45 00 00 # tcp协议头
68 65 6c 6c 6f 20 77 6f 72 6c 64 # data
- 以太网帧首部
- 目的MAC地址:6字节
- 源MAC地址:6字节
- 类型:2字节(通常为0x0800表示IP协议)
00 0c 29 8b 37 da # 目的MAC地址 (Destination MAC Address)
00 50 56 c0 00 08 # 源MAC地址 (Source MAC Address)
08 00 # 类型 (Type):0x0800,表示后续数据是IP数据包
- IP 数据报首部
45 00 00 33 28 5b 40 00 80 06 ba 80 0a 01 02 01 0a 01 02 07 # ip协议头
- 版本与头部长度(Version & IHL):
45
:4
表示IPv4
,5
表示头部长度为5
(即 )。 - 服务类型(Type of Service):
00
。 - 总长度(Total Length):
00 33
(即 51 字节)。 - 标识(Identification):
28 5b
(这是数据报的标识符,用于分片时识别不同的数据报)。 - 标志和片偏移(Flags & Fragment Offset):
40 00
(没有分片)。 - 生存时间(TTL):
80
(128,表示数据包可以经过 128 个路由器)。 - 协议(Protocol):
06
(表示TCP
协议)。 - 头部校验和(Header Checksum):
ba 80
(校验和,用于检测头部错误)。 - 源IP地址:
0a 01 02 01
(十六进制转换为10.1.2.1
)。 - 目标IP地址:
0a 01 02 07
(十六进制转换为10.1.2.7
)。
- TCP 段首部
30 39 25 1e 84 a4 e6 82 cf f2 ea 28 50 18 10 0a 7b 45 00 00 # tcp协议头
源端口号:30 39
(十六进制转换为 12345
)
目标端口号:25 1e
(十六进制转换为 9502
)
序列号:84 a4 e6 82
(32 比特序列号,十六进制值 0x84a4e682
)
确认号:cf f2 ea 28
(32 比特确认号,十六进制值 0xcff2ea28
)
数据偏移:50
(表示头部长度为 5 个 32 位字(即20字节))
窗口大小:18 10
(16 比特窗口大小,十六进制值 0x1810
,即 6160 字节)
校验和:0a 7b
(十六进制校验和,十六进制值 0xa7b
)
- 数据部分解析
68 65 6c 6c 6f 20 77 6f 72 6c 64 # data
这些字节对应的ASCII字符是:hello world
本文作者:Astron_fjh
本文链接:https://www.cnblogs.com/Astron-fjh/p/18615816
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步