humid1ch blogs

本篇文章

手机用户建议
PC模式 或 横屏
阅读


Linux网络 2024 年 11 月 29 日

[TCP/IP] 数据链路层协议: 以太网帧协议格式、局域网内部通信原理、ARP协议...

TCP/IP协议栈 四层模型, 应用层、传输层、网络层 以及数据链路层, 分别在网络通信中担任不同的角色
关于上面三层
  1. 应用层协议

    应用层协议, 通常是用户最需要关注的内容, 因为它关系着用户数据实际的格式, 决定了对端能否正确的解析出真实有效的数据, 以及数据的加密等内容

    常用的有HTTPHTTPS

  2. 传输层协议

    传输层协议的使用, 更多与通信的场景有关, 数据传输是否需要保障可靠性, 通信是否需要建立连接等等

    常用的有UDPTCP协议等

  3. 网络层协议

    网络层协议, 主要作用是要实现网络的构建, 并且为数据提供跨网络传输的能力

    常用的有IP协议等

局域网内的设备是可以直接通信的, 不用经过路由, 这是数据链路层能够实现的功能
数据链路层 的协议, 就是实际用于同一局域网内两节点之间传输数据的

以太网帧协议

网络硬件设备(网卡), 都有自己的物理地址 被称为MAC地址, MAC地址是硬件出场时就设定好的, 通常是全球唯一的(实际上并总是需要, 一般情况下只需要在所在网络内保持唯一就可以了)
MAC地址的长度为48位, 一般用16进制加上:表示, 比如:d8:80:83:21:02:95
MAC地址是用来确定局域网内唯一的网络设备的
此时, 可能会出现一个疑问: IP协议已经能让主机在网络中唯一了, 为什么还要用MAC地址确定局域网内的唯一设备呢?
因为, 数据从主机A发送到主机B的整个传输过程中, IP的作用除了能够确定网络中的唯一主机之外, 最主要的作用其实是路由
通过IP的网络号, 可以快速排除非目标网络, 进而实现数据的在不同网络中的快速路由
直到数据报文发送到目标网络之后, 并不会只通过IP地址确定局域网内的主机, 而是会通过IP查询局域网内对应设备的MAC地址, 获取到MAC地址之后, 才会向此MAC地址的设备 发送数据
而, 数据链路层协议, 就是通过MAC地址, 实现同一局域网内设备之间的通信
以太网 是数据链路层和物理层中, 运用最广泛的一种局域网技术标准
有线网络数据链路层协议即为: 以太网帧协议

以太网帧格式

以太网帧格式比较简单:

实际, 前边(左边)还存在两个字段7字节的前导码1字节的帧开始界定符

这两个字段内容是固定的, 用户不用考虑

  1. 6字节 目的MAC地址

    即, 目标局域网内 目标主机的MAC地址

  2. 6字节 源MAC地址

    即, 发送端主机的MAC地址

  3. 2字节 类型

    此字段用于区分以太网帧的数据类型

    以太网帧数据是存在不同类型的: IP ARP RARP

    0x0800表示 IPv4数据类型

    0x0806表示 ARP数据类型

    0x8035表示 RARP数据类型

  4. 46~1500字节 数据

    这里就是上层协议交付下来的数据 或 ARP RARP数据

    具体要根据上一个字段 判断

  5. 4字节 CRC

    即, 数据校验码

以太网帧 在数据链路层传输时, 主要依靠MAC地址定位唯一的设备, 所以 以太网帧又被称为MAC
MAC帧的非数据字段是固定的: 6Byte DestMAC + 6Byte SourceMAC + 2Byte DataType + 4Byte CRC
这可以很好的解决MAC帧的封装和解包的问题

数据在局域网内的传输**

同一局域网内的主机 是可以直接通信的, 因为局域网内的数据通常以以太网帧的形式流通
以太网帧确定唯一主机是由MAC地址确定的
当以太网帧填充好源MAC地址和目的MAC地址 和 数据 之后, 将数据发送到局域网中, 局域网中的设备就能根据以太网帧中的目的MAC地址接收数据
假设存在8台主机, 通过一根总线连接成一个局域网
此时MAC1要向MAC7发任意数据, 则MAC1会填充以太网帧:
MAC1主机 将封装完成的MAC帧发送到总线上, 就相当于发送到了局域网中
那么MAC7设备如何知道这数据是发给它的呢?
MAC7要想知道这个MAC帧是给它发送的, MAC7就要接收这个MAC帧 然后读取其中的目的MAC地址, 然后进行对比 才能确认. MAC7也确实是这样接收到数据的
即, 向局域网中发送的数据, 只有在目标设备接收到之后, 才能确认数据的目标是自己
这也就是说, 向局域网中发送的数据, 要想正确地抵达目的地, 局域网中的所有设备都要接收并读取一次MAC帧的目的MAC地址, 如果MAC地址对比正确, 就解包并向上层交付, 否则 就丢弃
构建局域网的这根总线, 连接着局域网中的所有主机
总线中有数据在传输时, 局域网中的所有主机都可以看见并接收数据, 而局域网中的主机各自又是独立的
所有主机共用一根总线进行数据传输, 就一定会出现一种现象: MAC1向总线中发数据的时, 已经有其他设备向总线中发送了数据
这种 数据帧在总线中传输时发生了碰撞 的现象, 叫做数据碰撞, 而会发生碰撞现象的局域网, 就被称为碰撞域
发生数据碰撞, 数据在总线中的传输会受到影响, 导致数据传输混乱
为了降低数据碰撞发生的概率, 碰撞域就应该越小越好, 即 局域网中的主机越少越好
而, 交换机最重要的功能之一就是划分碰撞域, 交换机的每一个端口都可以划分为一个碰撞域, 可以有效的减少数据碰撞的发生

在局域网内, 数据是以MAC帧的形式传输的, 确定唯一主机的依据是MAC地址
但是有一个问题: 发送方如何知道接收方的MAC地址?
MAC地址是网络设备的物理地址, 发送方明显是无法默认已知对方设备的MAC地址的
那么, 同一局域网中, 发送方发送数据时, 以太网帧中的目的MAC地址如何获取呢?
使用ARP协议进行询问

ARP协议

ARP协议全称为: Address Resolution Protocol地址解析协议, 是用来将IP地址解析为MAC地址的
但是, 并不是直接对IP地址本身进行解析, 而是通过IP地址进行MAC地址询问
IP地址, 在局域网内是唯一的, 即 可以表示局域网内的唯一主机
ARP协议, 就是用IP地址找局域网内的唯一主机, 并询问目标主机的MAC地址, 以获取目标主机的MAC地址

ARP协议格式

红色部分, 是以太网帧报头部分, 不用再多说

以太网帧中表示帧类型的字段填充不同值, 表示的帧类型不同

0x0800表示 IPv4数据类型

0x0806表示 ARP数据类型

0x8035表示 RARP数据类型

绿色部分, 则是APR帧数据格式:
  1. 2字节 硬件类型

    用于表示 数据链路层的网络类型, 1表示以太网

  2. 2字节 协议类型

    用于表示 网络层的协议类型, 即 要被转换的地址类型, 0x0800表示IPv4地址

  3. 1字节 硬件地址长度

    与第一个字段对应, 以太网地址长度为6字节

  4. 1字节 协议地址长度

    与第二个字段对应, IP地址长度为4字节

  5. 2字节 OP

    填充操作类型, 1表示ARP请求, 2表示ARP响应

  6. 6字节 发送端MAC地址

    发送 此ARP帧的设备的MAC地址

  7. 4字节 发送端IP地址

    发送 此ARP帧的设备的IP地址

  8. 6字节 目的端MAC地址

    ARP帧的目的设备的MAC地址

  9. 4字节 目的端IP地址

    ARP帧的目的设备的IP地址

ARP协议帧格式比较容易理解

目的MAC的获取过程

同一局域网中
以主机A (MAC:D8:80:83:21:02:95, IP:192.168.5.131)
主机B (MAC:08:00:27:03:FB:19, IP:192.168.5.135)为例
当主机A需要获取主机BMAC地址时, 主机A就会向局域网中发送ARP请求, 一般可能会将数据填充为:
目的MAC地址是未知的, 需要获取的
OP字段, 被填充为1 表示此帧为ARP请求帧, 是请求硬件地址的
而主机BIP, 即 表示要获取哪一个硬件的地址, 此例中为 主机B对应IP的硬件
局域网内的主机, 接收到此ARP帧之后:
  1. 首先, 读取目的MAC地址, 辨别自己是否为目标主机 (广播)
  2. 然后, 读取帧类型字段, 辨别出是ARP
  3. 然后, 读取ARP帧的**OP**字段, 辨别出是ARP请求
  4. 然后, 读取ARP帧的**目的IP**字段, 辨别自己是否为目标主机
当主机B收到此APR请求帧之后, 就会进行应答, 一般可能会将数据填充为:
ARP应答帧填充的比较完整
OP字段, 被填充为2 表示此帧为ARP应答帧, 即 此帧中填充有请求结果
局域网内的主机, 接收到此APR帧之后:
  1. 首先, 读取目的MAC地址, 辨别自己是否为目标主机
  2. 然后, 读取帧类型字段, 辨别出是ARP
  3. 然后, 读取ARP帧的**OP**字段, 辨别出是ARP应答
  4. 然后, 读取ARP帧的**发送方IP发送方MAC**字段, 获取到IP对应的MAC地址
当主机A收到此ARP之后, 就能获取到目标IP对应的目标MAC

MTU 最大传输单元

IP协议报头中存在三个字段, 是关于数据分片
IP协议可能需要对传输层交付下来的数据进行分片
IP协议可能需要进行分片的原因就是 数据链路层存在一个MTU
MTU是数据链路层中, 传输的单个帧中数据字段的最大字节数
以太网帧为例:
数据字段的大小范围是: [46, 1500]
即, 以太网帧的MTU1500字节, 这是标准规定的, 当数据大小不在此范围内, 数据链路层就会丢弃上层交付下来的数据, 不进行传输
因此, 当网络层从传输层接收到的数据在封装之后超过1500字节时, IP协议就需要对数据进行分片

数据链路层存在MTU一定是为了传输效率考虑的

因为数据链路层主要是负责局域网内通信的, 数据帧在局域网总线中传输时, 可能会发生碰撞, 此时就需要让数据帧保持一个相对合适的长度

如果过长, 为了避免碰撞, 等待数据传输的时间就会过长, 影响传输效率

如果过短, 需要传输的帧数量就会提升, 可能会更高频率的发生碰撞, 同样会影响传输效率

Windows平台, 可以在Powershell执行Get-NetIPInterface查看设备的MTU:
Linux平台, 则可以通过ifconfig查看网络设备的MTU:

MTUIP协议的影响

对于IP协议来说, IP协议保证向下交付的数据大小不能超过MTU, 所以 IP协议需要对 传输层交付过来的较大的数据进行分片处理
如果传输层交付到网络层的数据较大, 网络层不进行分片, 数据链路层就会丢弃过大的数据

MTUUDP协议的影响

UDP协议是无连接的、不可靠的传输协议
如果UDP协议向网络层交付的数据包过大, 并且IP协议没有对UDP数据包进行分片, 那么UDP数据包在数据链路层会被直接丢弃
UDP是不可靠的传输协议, 被丢弃的数据包不会进行重传, UDP数据包丢失就是丢失了
也就是说, MTU可能会导致UDP数据包丢失

MTUTCP协议的影响

TCP协议虽然是可靠的传输协议, 但是由于MTU的存在, 还是不能无限制的大
如果TCP数据过大, IP协议就会更多的进行分片, 分片越多分片丢失个概率越大. 单个分片丢失, 就认为整个TCP数据都丢失了, TCP协议就会进行重传, 会影响TCP通信的效率

为了减少分片, TCP报头选项中存在一个字段MSS(Max Segment Size), 此字段表示TCP单个数据报的最大长度
MSS字段可以在建立TCP连接时 协商双方支持的MSS, 最终选择较小值作为本次连接的MSS
MSS表示的是 一个完整的TCP数据报的最大长度, 即 TCP能交付给IP协议的最大长度
版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)

作者: 哈米d1ch 发表日期:2024 年 11 月 29 日