目录
数据链路层的作用
- 我们知道数据能在网络中从一台主机发送到另一台主机,是通过IP协议来实现的,但是IP协议仅仅是保证了数据在网络中能够发送,并不能保证数据的可靠性,因此IP需要上层TCP/UDP来提供可靠性的保证,如果数据在传输过程中丢包了,TCP就会让IP重新发送数据,最终在TCP机制下保证数据可靠的发送到对端;
- 数据在网络中需要一跳一跳的从一台主机发送到另一台主机,最终发送到目标主机,这也就意味着两台主机是相连接的,处于同一网段,本质上就是在进行子网间的转发,当我们决定将数据交给下一个路由器时,就意味着下一个路由器一定跟我们处于同一个局域网,但是,IP协议虽然解决了数据在网络中的传输问题,但是路由器与路由器之间的传输问题并不是IP协议去解决的,这就是数据链路层之间需要解决的了,也就是说,IP并没有解决路由转发的具体功能,而是提供路由转发的具体策略;
- 也就是说,网络层IP提供的是跨网络发送数据的能力,传输层TCP是为数据发送提供可靠性保证的,而链路层解决的则是两台相连主机之间的通信问题。
认识以太网
- "以太网" 不是一种具体的网络,而是一种技术标准;既包含了数据链路层的内容,也包含了一些物理层的
内容。例如:规定了网络拓扑结构,访问控制方式,传输速率等; - 例如以太网中的网线必须使用双绞线;传输速率有10M,100M,1000M等;
- 以太网是当前应用最广泛的局域网技术;和以太网并列的还有令牌环网,无线LAN等;
以太网通信原理
- "以太网"不是一种具体的网络,而是一种技术标准,它既包含了数据链路层的内容,也包含了一些物理层的内容。例如,以太网规定了网络拓扑结构,访问控制方式,传输速率等。
- 以太网中的网线必须使用双绞线,传输速率有10M,100M,1000M等。
以太网中所有的主机共享一个通信信道,当局域网中的一台主机发出数据后,该局域网中的所有主机都能够收到该数据。
- 当主机A想要给主机D发消息时,其实所有的主机都能够接收到主机A所发送的消息,但是最终只有主机D会对收到的数据进行向上交付;
- 局域网中的其他主机虽然收到了主机A所发送来的数据,但是知道识别到不是自己所需要的数据时,就会对该数据进行丢弃。
也就是说,在进行局域网通信的时候,局域网当中的所有主机都能够看到局域网中传输的任何数据,只不过每个主机都只关心发送给自己的数据罢了。
碰撞避免算法
以太网中的所有主机共享一个通信通道,所以在同一时间内只允许有一台主机发送数据,否则各个主机发送的数据就会相互干扰,站在系统的角度来看,这里各个主机所共享的通信信道就是一种临界资源,这个临界资源同一时刻只允许一台主机使用。
- 以太网的解决办法就是对各个主机的发送能力并不进行限制,你想发数据就发,但是如果发出去的数据之间发生了碰撞,就要执行碰撞避免算法;
- 所谓碰撞避免算法就是当某个主机发送出去的数据发生碰撞时,该主机会等待一段时间后进行数据重发,这样就能保证在局域网中的数据能够尽可能的消散;
也就是说,以太网中主机发送的数据产生碰撞后该主机会执行碰撞避免算法,所以我们说以太网是基于碰撞区和碰撞检测的局域网通信标准。
碰撞避免算法就是主机等待一段时间后重新发送数据,因此以太网底层也有重传机制,只不过以太网的重传机制只是为了保证将数据从局域网中的一台主机发送到另一台主机。
以太网帧格式
- 源地址和目的地址是指网卡的硬件地址(也叫MAC地址),长度是48位,是在网卡出厂时固化的;
- 帧协议类型字段有三种值,分别对应IP协议、ARP协议和RARP协议;
- 帧末尾是CRC校验码。
如何分离?
以太网MAC帧的帧头和帧尾都是固定长度的,因此当底层收到一个MAC帧后,直接提取出MAC帧当中固定长度的帧头和帧尾,此时剩下的就是有效载荷了。
如何交付?
以太网MAC帧对应的上层协议不止一种,因此在将MAC帧的报头和有效载荷分离后,还需要确定应该将分离出来的有效载荷交付给上层的哪一个协议。在MAC帧的帧头当中有2个字节的类型字段,因此在分离出报头和有效载荷后,根据该字段将有效载荷交付给对应的上层协议即可。
认识MAC地址
- MAC地址用来识别数据链路层中相连的节点;
- 长度为48位,及6个字节,一般用16进制数字加上冒号的形式来表示,例如:08:00:27:03:fb:19;
- 在网卡出厂时就确定了,不能修改,MAC地址通常是唯一的(虚拟机中的MAC地址不是真实的MAC地址,可能会冲突;也有些网卡支持用户配置MAC地址)。
通过ifconfig
命令我们可以查看MAC地址:
对比理解MAC地址和IP地址
实际数据在路由过程中会存在两套地址,一套是源IP地址和目的IP地址,还有一套是源MAC地址和目的MAC地址。
- IP地址描述的是路途总体的起点和终点。
- MAC地址描述的是路途上的每一个区间的起点和终点。
因此数据在路由过程中,源IP地址和目的IP地址可以理解成是不会变化的,而数据每进行一跳后其源MAC地址和目的MAC地址都会变化。
认识MTU
MTU(Maximum Transmission Unit,最大传输单元)描述的是底层数据帧一次最多可以发送的数据量,这个限制是不同的数据链路层对应的物理层产生的。
- 以太网帧中的数据长度规定最小46字节,最大1500字节,ARP数据包的长度不够46字节,要在后面补填充位;
- 最大值1500称为以太网的最大传输单元(MTU),不同的网络类型有不同的MTU;
- 如果一个数据包从以太网路由到拨号链路上,数据包长度大于拨号链路的MTU了,则需要对数据包进行分片(fragmentation);
- 不同的数据链路层标准的MTU是不同的。
如果IP层一次发送的数据超过了最大传输单元MTU,此时就需要对数据进行分包,然后才能继续向下传输:
- 将较大的IP包分成多个小包,并给每个小包打上标签;
- 每个小包IP协议头的 16位标识(id) 都是相同的;
- 每个小包的IP协议头的3位标志字段中,第2位置为0,表示允许分片,第3位来表示结束标记(当前是否是最后一个小包,是的话置为1, 否则置为0);
- 到达对端时再将这些小包,会按顺序重组,拼装到一起返回给传输层;
- 一旦这些小包中任意一个小包丢失,接收端的重组就会失败,但是IP层不会负责重新传输数据。
在IP层中,不仅仅源端主机会进行数据的分片,数据在路由的过程中也会进行分片,因为不同的网络MTU可能是不一样的,如果传输路径上的某个网络MTU要比源端主机上的MTU小,数据在路由的过程中就可能会产生分片。
MTU对UDP协议的影响
- 如果不携带选项字段,IP报头的长度为20字节,UDP采用的是定长8字节报头,一旦UDP携带的数据超过1500 - 20 - 8 = 1472 字节,就会在IP层进行分片;
- 这分片的IP数据报有任意一个丢失,都会引起接收端网络层重组失败,那么这就意味着,如果UDP数据报在网络层被分片,整个数据被丢失的概率就大大增加了。
MTU对TCP协议的影响
- TCP发送的数据报不能无限大,还是应该受制于MTU,我们将TCP的单个数据报的最大报文长度,称为MSS(Max Segment Size)。
- TCP通信双方在建立连接的过程中,就会进行MSS协商,最终选取双方支持的MSS值当中的较小值作为最终MSS。
- MSS的值实际就是在TCP首部的40字节的选项字段当中的(kind=2)。
- 最理想的情况下,MSS的值正好就是在数据不会在IP层进行分片的最大长度。
MSS和MTU的关系:
一旦TCP携带的数据超过1500 - 20(IP报头大小)- 20(TCP报头大小)= 1460字节,就会在IP层进行分片。
我们可以使用ifconfig
命令产看MTU的大小:
数据跨网络传输的过程
- 当主机A想要跨网络对主机B进行数据传输时,需要先将数据交给同局域网的路由器A,此时主机A就会将封装好的MAC帧发送到局域网中,此时MAC帧的MAC源地址和MAC目的地址就是主机A的MAC源地址和MAC目的地址;
- 主机A所在的局域网中所有的主机都会接收到此MAC帧,但是只有路由器A发现该MAC帧目的地址与自己的MAC帧地址相同,就会进行解包,将解包以后的数据交付IP层;
- 当路由器A的IP层接收到接收到主机A发来的数据以后,会提取出IP报头中IP目的地址,通过对路由表的查询将数据转发给路由器B,该过程中路由器A就会再将数据向下交付,重新封装MAC帧,此时封装后的MAC帧当中的源MAC地址和目的MAC地址,就变成了路由器A的MAC地址和路由器B的MAC地址。
- 虽然与路由器A直接相连的主机虽然也可能有很多,但最终只有路由器B发现该MAC帧当中的目的MAC地址与自己的MAC地址相同,于是才会对该MAC帧进行解包,并将解包后剩下的IP数据报交付给IP层。
- ...
- 不断重复上述过程,最终将数据传输给主机B。
因此数据在进行跨网络传输时,其对应的源IP地址和目的IP地址一般是不会变化的,而该数据的源MAC地址和目的MAC地址却是一直在变化的,根本原因就是因为该数据对应的上一跳主机和下一跳主机在不断变化。
ARP协议
地址解析协议(Address Resolution Protocol,ARP)协议,是根据IP地址获取MAC地址的一个TCP/IP协议。
ARP协议作用
对于路由器A来说,想要将数据转发给路由器B,仅仅只知道目的IP地址是不够的,还需要知道对方的MAC地址,因为不知道MAC地址,我们就无法封装MAC帧。所以在同一个网段内,我们需要通过IP地址得到对方的MAC地址,这就叫做ARP协议。
网络协议栈自上向下分为应用层,传输层,网络层和数据链路层,ARP、RARP和MAC帧协议虽然都属于数据链路层的协议,但ARP协议和RARP协议属于MAC帧的上层协议。
MAC帧的上层协议不一定就直接是网络层的协议,MAC帧的上层协议有可能也属于数据链路层的协议,但就是位于MAC帧的上层。与之类似的,网络层当中的ICMP协议和IGMP协议,这两个协议虽然与IP协议都属于网络层,但这两个协议属于IP的上层协议。
ARP数据报的格式
- 硬件类型指链路层的网络类型,1为以太网;
- 协议类型指要转换的地址类型,0x0800为IP地址;
- 硬件地址长度对于以太网地址为6字节,因为MAC地址是48位的;
- 协议地址长度对于IP地址为4字节,因为IP地址是32位的;
- op字段为1表示ARP请求,op字段为2表示ARP应答。
ARP协议的工作流程
假设此时路由器D要给主机B发数据,我们除了需要知道目的IP地址以外还需要知道对方的MAC地址,所以我们首先要做的就是ARP请求动作。
ARP请求
- 路由器构建ARP请求,将ARP请求当中op字段设置为1;
- ARP请求当中硬件类型字段设置为1,因为当通信方式为以太网通信;
- ARP请求当中协议类型字段设置为0800,因为此时需要根据目的IP地址来获取主机B的MAC地址;
- 硬件地址长度设置为6,因为MAC地址是48位的;
- 协议地址长度设置为4,因为IP地址是32位的;
- 发送端以太网地址对应的就是路由器D的MAC地址;
- 发送端IP地址对应的就是路由器D的IP地址;
- 目的以太网地址就是主机B的MAC地址,但是我们此时并不知道主机B的MAC地址,所以我们将其二进制序列全设置为1,表示在局域网中进行广播;
- 目的IP地址就是主机B的IP地址。
此时构建的ARP请求如下:
ARP请求构建完成后,为了能将ARP请求发送到以太网当中,还需要将ARP数据包向下交付给MAC帧协议,封装成MAC帧:
- MAC帧首部中以太网目的地址就是主机B的MAC地址,由于我们此时并不知道,所以我们将其二进制序列全设置为1;
- 以太网源地址就是路由器D的MAC地址;
- 帧类型我们设置为0806,因为这儿构建的是ARP请求,因此MAC帧当中的帧类型字段设置为0806。
MAC帧:
MAC帧封装完毕后,此时路由器D就会将封装好的MAC帧以广播的形式发送到局域网中:
- 由于是以广播的形式将MAC帧发送到局域网中,所以每个主机都可以接收到路由器D的MAC帧,当每台主机接收到该MAC帧以后,都会将MAC进行解包,该MAC帧帧类型字段为0806,构建的是一个ARP应答或者是请求,每台主机都会向上交付给ARP层;
- ARP层接收到该数据包以后,会发现ARP数据包的op字段为1,表示构建的是ARP请求,然后提取出ARP中的目的IP地址,最终只有主机B会发现ARP数据包中的目的IP地址与自己IP地址相同,其他主机识别到ARP数据包中的目的IP地址与自己IP地址不同以后,就会将此ARP数据包进行丢弃,最终只有主机B会对该ARP请求进行应答;
注意:
局域网其他主机收到该ARP请求以后,并不是在MAC帧层进行丢弃的,而是在ARP层进行丢弃的。
ARP应答
主机B接收到路由器D发来的ARP请求以后,就会构建ARP应答:
- 由于此时构建的是ARP应答,op字段就会被设置为2;
- ARP应答当中的硬件类型,协议类型,硬件地址长度,协议地址长度跟ARP请求当中设置的一样即可;
- 而此时ARP应答中的发送端以太网地址和发送端IP地址就是主机B的MAC地址和IP地址;
- 由于我们接收到的是路由器D的ARP请求,所以此时ARP应答中的目的以太网地址就是路由器D的MAC地址,目的IP地址也就是路由器IP地址。
ARP应答构建完成以后,也需要向下交付封装成MAC帧:
- 此时MAC帧首部中以太网目的地址和以太网源地址分别对应路由器D的MAC地址和主机B的MAC地址;
- 这里封装的是一个ARP应答数据包,因此MAC帧当中的帧类型字段设置为0806。
至此,ARP应答封装MAC帧完成。
封装MAC帧完成以后,就会将数据发送到局域网中,但是此时并不是以广播的形式发送了,因为此时我们已经知道目的以太网地址:
- 此时尽管局域网内的所有主机都可以收到该MAC帧,但是不相干的主机收到MAC帧以后,并不会向上交付给ARP协议了,他们会立马识别出目的以太网地址与自己的MAC地址不同,然后将该数据包进行丢弃,最终只有路由器D会将解包后MAC帧的有效载荷向上交付给自己的ARP层。
- 当路由器D的ARP层收到这个数据包后,发现ARP数据包当中的op字段为2,于是判定这是一个ARP应答,然后就会提取出ARP数据包当中的发送端以太网的地址和发送端IP地址,此时路由器D就拿到了主机B的MAC地址。
我们会发现,在ARP请求和ARP应答过程中出现了两次丢弃,但是ARP请求过程中是在ARP层进行丢弃的,而ARP应答过程中是在MAC层进行丢弃的。
是不是每一次数据发送都需要进行一个请求和一个应答呢?
不是,因为ARP请求成功以后,请求方就会将IP:MAC的映射关系给保存下来,此时下一次请求可以直接进行使用了。
ARP最终只会在目标子网中进行吗?其他过程中会不会发生呢?
ARP的过程在网络路径中随时都有可能发生的。
为什么MAC帧的报头当中已经涵盖了源和目的MAC地址,ARP的报头当中还要有这两个字段?
MAC帧和ARP尽管都属于数据链路层,但是MAC帧和ARP在数据链路层依然是属于上下层的,因此它们不会互相关心彼此报头当中的数据。此外,如果底层网络采用的不是以太网,而是其他类型的网络,此时ARP层的MAC地址就是必要的了。
在进行局域网通信时,为什么不直接以广播的方式发送数据?
在进行局域网通信时,就算只知道对方的IP地址,而不知道对方的MAC地址,也可以以广播的方式将数据发送到局域网当中,此时局域网当中的主机也能够在IP层比对目的IP地址与自己是否相符,来判断收到的这个数据是否是发送给自己的。
理论上确实可以这样,但这种方式是不妥的。
- 对于局域网当中的大多数主机来说,收到的这个报文其实早就应该被丢弃,而现在这个报文却交付到了IP层,我们都知道IP层是属于操作系统管控的,因此这对网络资源和系统资源来说都是一种浪费。
- 因此在底层MAC帧层就应该判定这个报文是不是发送给当前主机的,而不是当数据向上交付到了IP层再来判断。
此外,如果无脑使用广播的方式来进行数据的发送,会使得广播和单播的概念变得模糊不清,你明明是想发送数据给局域网当中的一台主机,但你却采用了广播的方式,这显然是不合理的。
ARP缓存表
实际不是每次要获取对方的MAC地址时都需要发起ARP请求,每次发起ARP请求后都会建立对应主机IP地址和MAC地址的映射关系,每台主机都维护了一个ARP缓存表,我们可以用arp -a
命令进行查看。
需要注意的是,缓存表中的表项有过期时间,这个时间一般为20分钟,如果20分钟内没有再次使用某个表项,那么该表项就会失效,下次使用时就需要重新发起ARP请求来获得目的主机的硬件地址。