数据链路层解决的问题
以太网协议
不同局域网所采用的通信技术可能是不同的,常见的局域网技术有以下三种:
以太网:以太网是一种计算机局域网技术,一种应用最普遍的局域网技术。令牌环网:令牌环网常用于IBM系统中,在这种网络中有一种专门的帧称为“令牌”,在环路上持续地传输来确定一个节点何时可以发送包。无线LAN/WAN:无线局域网是有线网络的补充和扩展,现在已经是计算机网络的一个重要组织部分。
虽然网络中各个局域网所采用的通信技术可能的不同的,但是IP屏蔽了底层网络的差异,对于网络通信双方的IP层及其往上的协议来说,它们并不需要关心底层具体使用的是哪种局域网技术。
- 数据在发送之前会先进行数据封装,此时链路层会给数据封装上对应的局域网的报头。
- 如果数据要进行跨网络传输,那么就需要经过路由器转发。
- 当数据在路由器进行向上交付时,会将该数据对应的局域网报头去掉。
- 而当路由器该数据转发给下一跳之前,又会给该数据封装上下一跳网络所对应的局域网报头。
也就是说,网络中的路由器会不断去掉数据旧的局域网报头,并添加上新的局域网报头,因此数据在进行跨网络传输时,就算所需跨越的网络采用的是不同的局域网技术,最终也能够正确实现跨越。
- “以太网” 不是一种具体的网络,而是一种技术标准,他既包含了数据链路层的内容,也包含了一些物理层的内容。例如,以太网规定了网络拓扑结构,访问控制方式,传输效率等。
- 以太网中的网线必须使用双绞线,传输效率有10M,100M,1000M等。
以太网中所有主机共享一个通信信道,当局域网中的一台主机发出数据后,该局域网中的所有主机都能够收到该数据。
- 比如当局域网中的主机A想要发送数据给主机B时,其实局域网当中的每一台主机都能够收到主机A发出去的数据,只不过最终只有主机B会将主机A发来的数据向上进行交付。
- 局域网当中的其他主机虽然也收到了主机A发送的数据,但经过识别后发现这个数据不是发送给自己的,于是就会直接将该数据丢弃而不会向上进行交付。
也就是说,在进行局域网通信时,局域网当中的所有主机都能够看到局域网中传输的任何数据,只不过每个主机都只关心发送给自己的数据罢了。
扩展:
- 网络抓包不仅能够抓到发送给自己的报文数据,也能抓取到发给别人的报文数据,实际就是因为在进行网络抓包时,主机将从局域网中收到的所有报文数据都向上交付了而已。
- 网卡有一种模式叫做混杂模式,被设置为混杂模式的网卡能够接受所有经过它的数据流,而不论其目的地址是否是它。
碰撞避免算法
由于以太网中的所有主机共享一个通信信道,因此在同一时刻只允许有一台主机发送数据,否则各个主机发送的数据就会互相干扰。站在系统的角度来看,这里各个主机所共享的通信信道就是一种临界资源,这个临界资源同一时刻只允许同一台主机使用。
- 对于这个问题,以太网的做法就是先不各个主机发送数据的能力,局域网中的每个主机想发送数据的时候直接发就行了,但是只要发送出去的数据与其他主机发送的数据产生了碰撞,那就得执行碰撞避免算法。
- 所谓的碰撞避免算法就是,当主机发送出去的数据产生碰撞时,该主机需要等待一段时间后再进行数据重发,在主机等待的时候就能够尽可能让局域网当中的数据消散。
- 以太网通信的原理就像现实生活中开会一样,在开会过程中同一时刻只允许一个人发言,如果两个人突然同时说话,那么双方都会礼貌的等待别人先说。
也就是说,以太网中主机发送的数据产生碰撞后,该主机会执行碰撞避免算法,所以我们说以太网是基于碰撞区和碰撞检测的局域网通信标准。
碰撞避免算法就是主机等待一段时间后重新发送数据,因此以太网底层也有重传机制,只不过以太网的重传机制只是为了保证将数据从局域网中的一台主机发送到另一台主机。
以太网帧格式
以太网帧格式如下:
- 源地址和目的地址是指网卡的硬件地址(也叫MAC地址),长度是48位,是在网卡出厂时固化的。
- 帧协议类型字段有三种值,分别对应
IP协议、ARP协议和RARP协议。 - 帧末尾是CRC校验码。
MAC帧如果将报头与有效载荷进行分离?
以太网MAC帧的帧头和帧尾都是固定长度的,因此当底层收到一个MAC帧后,直接提取出MAC帧当中固定长度的帧头和帧尾,此时剩下的就是有效载荷了。
MAC帧如何决定将有效载荷交付给上层的哪一个协议?
以太网MAC帧对应的上层协议不止一种,因此在将MAC帧的报头和有效载荷分离后,还需要确定应该将分离出来的有效载荷交付给上层哪一个协议。
在MAC帧的帧头当中有2个字节的类型字段,因此在分离出报头和有效载荷后,根据该字段将有效载荷交付给对应的上层协议即可。
举个例子
当主机A将该MAC帧发送到局域网当中后,局域网当中的所有主机都可以收到这个MAC帧,包括主机A自己。
- 主机A收到该MAC帧后,可以对收到的MAC帧进行CRC校验,如果校验失败则说明数据发送过程中产生了碰撞,此时主机A就会执行碰撞避免算法,后续进行MAC帧重发。
- 主机B收到该MAC帧后,提取出MAC帧当中的目的地址,发现该目的地址与自己的MAC地址相同,于是在CRC校验成功后就会将有效载荷交付给上层IP层进行进一步处理。
- 局域网中的其他主机收到该MAC帧后,也会提取出MAC帧当中的目的地址,但发现该目的地址与自己的MAC地址不匹配,于是就会直接将这个MAC帧丢弃掉。
认识MAC地址
对比MAC地址和IP地址
- IP地址描述的是路途总体的起点和终点。
- MAC地址描述的是路途上的每一个区间的起点和终点。
认识MTU
MTU(Maximum Transmission Unit,最大传输单元) 描述的是底层数据帧一次最多可以发送的数据量,这个是不同的数据链路层对应的物理层产生的。
- 以太网对应的MTU的值一般是1500字节,不同的网络类型有不同的MTU,如果一次要发送的数据超过了MTU,则需要在IP层对数据进行分片。
- 此外,以太网规定MAC帧中数据的最小长度为46字节,如果发送数据量小于46字节,则需要在数据后面补填充位,比如ARP数据包的长度就是不够46字节的。
MTU对IP协议的影响
因为数据链路层规定了最大传输单元MTU,所以如果IP层一次要发送的数据量超过了MTU,此时IP层就需要先对数据进行分片,然后才能将分片后的数据向下交付。
- IP层会将较大的数据进行分片,并给每个分片的数据包进行标记,具体就是通过设置IP报头当中的16位标识、3位标志和13位偏移来完成的。
- 由同一个数据分片得到的各个分片报文,所对应的IP报头当中的16位标识(id)都是相同的。
- 每一个分片报头的IP报头当中的3位标志字段中,第2位设置为0,表示允许分片,第3位用作结束标记(最后一个分片报文设置为0,其余分片报文设置为1)。
- 当对端IP层收到这些分片报文后,需要先将这些分片报文按照顺序进行组装,拼装到一起后再向上交付给传输层。
- 如果分片后的某个报文在网络传输过程中丢包了,那么对端在进行数据组装时就会失败,此时就需要上层传输层进行数据重传。
数据的分片和组装发生在IP层,不仅源端主机可能会对数据进行分片,数据在路由过程中路由器也可能会对数据进行分片。因为不同网络的MTU是不一样的,如果传输路径上的某个网络的MTU比源端网络的MTU小,那么路由器就可能对IP数据报再次进行分片。
MTU对UDP协议的影响
IP报头当中如果不携带选项字段,那么IP报头的长度就是20字节,而UDP一次携带的数据超过了 1500 - 20 - 8 = 1427字节,此时数据就需要在IP层进行分片。
- 分片后得到的多个IP数据报中有任意一个在传输过程中丢失,都会引起接收端IP层重组失败。
- 假设在网络传输时丢包的概率时万分之一,如果将数据拆分为一百份进行发送,那么此时丢包的概率就上升到了百分之一。
- 因为只要有一个分片报文丢包了也就等同于这个报文整体丢失了,因此分片会增加UDP报文丢包的概率。
MTU对TCP协议的影响
对于TCP来说,分片也会增加TCP报文丢包的概率,但与UDP不同的是TCP丢包后还需要进行重创,因此TCP应该尽量减少分片导致的数据重传。
- TCP发送的数据报不能无限大,还是应该受制于MTU,我们将TCP的单个数据报的最大报文长度,称为
MSS(Max Segment Size)。 - TCP通信双方在建立连接的过程中,就会进行MSS协商,最终选取双方支持的MSS值当中的较小值作为最终MSS。
- MSS的值实际就是在TCP首部的40字节的选项字段当中的(kind=2)。
- 最理想的情况下,MSS的值正好就是在数据不会在IP层分片的最大长度。
MSS和MTU的关系如下:
数据跨网络传输的过程
以主机A将数据跨网络传输给主机D为例,数据路由的过程如下:
- 主机A要想将数据跨网络传输给主机B,需要先将数据交给同局域网当中的路由器A,因此主机A需要将封装好的MAC帧发送到当前局域网当中,此时MAC帧当中的源MAC地址和目的MAC地址,对应就是主机A的MAC地址和路由器A的MAC地址。
- 此时主机A所在的局域网当中所有主机都能够收到这个MAC帧,但最终只有路由器A发现该MAC帧当中的目的MAC地址与自己的MAC地址相同,于是才会对该MAC帧进行解包,并将解包后剩下的IP数据报交付给IP层。
- 路由器A的IP层拿到解包后的IP数据报后,会提取出IP报头当中的目的IP地址,然后通过查询路由表后确定需要将该数据转发给路由器B,于是路由器A再将数据向下进行交付,重新封装MAC帧的帧头和帧尾,但此时封装后的MAC帧当中的源MAC地址和目的MAC地址,就变成了路由器A的MAC地址和路由器B的MAC地址。
- 与路由器A直接相连的主机虽然也可能有很多,但最终只有路由器B发现该MAC帧当中的目的MAC地址与自己的MAC地址相同,于是才会对该MAC帧进行解包,并将解包后剩下的IP数据报交付给IP层。
- 路由器B的IP层拿到解包后的IP数据报后,同样会提取出IP报头当中的目的IP地址,并通过查询路由表后确定需要将该数据转发给路由器C,于是路由器B再将数据向下进行交付,重新封装MAC帧和帧头和帧尾,但此时封装后的MAC帧当中的源MAC地址和目的MAC地址又变成了路由器B的MAC地址和路由器C的MAC地址。
- …
- 不断的重复上述过程,直到最终数据转发至主机B。
IP网络
数据跨网络传输的过程就像现实生活中运输包裹的过程一样。
- 数据每到一个新的局域网就需要封装上对应局域网标准的报头,就像包裹在运输的不同阶段可能会使用不同的交通工具,比如:火车、汽车、自行车。
- 但站在IP层看到的数据内容始终是一样的,就像我们最终看到的始终是同一个包裹一样。
- 包裹运输时使用的不同的交通工具,对应就是数据经过不同局域网时所添加的MAC帧报头,而包裹对应就是MAC帧的有效载荷,即IP数据报。
也就是说,数据在跨网络传输过程中,其对应的MAC帧的报头是不断变化的,而MAC帧当中的IP数据报当中的内容是不变的,所以站在IP层看到的数据内容是一样的,这就是为什么现在主流的网络叫做"IP网络"的原因。
ARP协议
ARP协议的作用
为什么回纯在ARP这样的协议?
以刚才的例子为例,当数据从主机A经过各种路由器转发到路由器J,此时路由器J就需要将数据转发给主机D完成数据的路由。
- 由于路由器J和主机D是属于同一个局域网的,因此路由器J能够直接将数据交给主机D,但要给同局域网中的一台主机发送数据,前提是得先知道对方的MAC地址。
- 但路由器J此时只知道主机D的IP地址,因此路由器J必须通过某种方式得到主机D的MAC地址。
ARP协议的定位
在TCP/IP四层模型中,网络协议栈自顶向下分为应用层、传输层、网络层和数据链路层。
其中应用层最典型的协议有HTTP、HTTPS和DNS等,传输层最典型的协议有TCP和UDP、网络层最典型的协议就是IP、数据链路层最典型的协议就是MAC帧协议,但实际数据链路层还有两种协议叫做ARP和RARP。
ARP、RARP和MAC帧协议虽然都属于数据链路层的协议,但ARP协议和RARP协议属于MAC帧的上层协议。
- 也就是说,MAC帧的上层协议不一定就直接是网络层协议,MAC帧的上层协议有可能也属于数据链路层的协议,但就是位于MAC帧的上层。
- 与之类似的,网络层当中的ICMP协议和IGMP协议,这两个协议虽然与IP协议都属于网络层,但这两个协议属于IP层的上层协议。
ARP数据的格式
ARP数据的格式如下:
- 硬件类型指链路层的网络类型,1为以太网。
- 协议类型指要转换的地址类型,0x0800为IP地址。
- 硬件地址长度对于以太网地址为6字节,因为MAC地址是48位的。
- 协议地址长度对于IP地址为4字节,因为IP地址是32位的。
- op字段为1表示ARP请求,op字段为2表示ARP应答。
从ARP的数据格式也可以看出,ARP是MAC帧协议的上层协议,ARP数据格式中的前3个字段和最后一个字段对应的就是以太网首部,但由于ARP数据包的长度不足46字节,因此ARP数据包在封装成为MAC帧时还需要补上18字节的填充字段。
ARP协议的工作流程
ARP请求的过程
首先路由器J需要先构建ARP请求。
- 首先,因为路由器J构建的是ARP请求,因此ARP请求当中的op字段设置为1。
- ARP请求当中的硬件类型字段设置为1,因为当前使用的是以太网通信。
- ARP请求当中的协议类型设置为0800,因为路由器是要根据主机D的IP地址来获取主机D的MAC地址。
- ARP请求当中的硬件地址长度和协议地址长度分别设置为6和4,因为MAC地址的长度是48位,IP地址的长度是32位。
- ARP请求当中的发送端以太网地址和发送端IP地址,对应的就是路由器J的MAC地址和IP地址。
- ARP请求当中的目的以太网地址和目的IP地址,对应就是主机D的MAC地址和IP地址,但由于路由器J不知道主机D的MAC地址,因此将目的以太网地址的二进制序列设置为全1,表示在局域网中进行广播。
此时ARP请求构建完成,如下:
ARP请求构建完成后,为了能够将ARP请求发送到以太网当中,还需要将ARP数据包向下交付给MAC帧协议,封装成MAC帧。
- 封装MAC帧报头时,以太网目的地址和以太网源地址,分别对应的是主机D和路由器J的MAC地址,但由于路由器J不知道主机D的MAC地址,因此MAC帧报头当中的以太网目的地址的二进制序列也只能设置为全1,表示在局域网中进行广播。
- 因为这里封装的是一个ARP请求数据包,因此MAC帧当中的帧类型字段设置为0806。
- 由于ARP请求数据包的长度只有28字节,不足46字节,因此还需要再MAC帧的有效载荷当中补上18字节的填充字段,最后再对MAC帧进行CRC校验即可。
此时ARP请求就被封装成MAC帧了,如下:
MAC帧封装完毕后,路由器J就可以将封装好的MAC帧以广播的方式发送到局域网当中了。
- 因为这个MAC帧是以广播的方式发出来的,因此局域网当中的每台主机收到这个MAC帧后,都会对该MAC帧进行解包。当这些主机识别到MAC帧当中的帧类型字段为0806后,便知道这是一个ARP的请求或应答的数据包,于是会将MAC帧的有效载荷向上交付给ARP层。
- 当ARP层收到这个数据包后,发现ARP数据包当中的op字段为1,于是判定这是一个ARP请求,然后再提取出ARP数据包当中的目的IP地址字段,虽然局域网当中的所有主机都会将该数据包交给自己的ARP层,但最终只有主机D发现ARP数据包当中的目的IP地址与自己相同,因此只有主机D会对该ARP请求进行应答,而局域网当中的其他主机在识别到ARP数据包当中的目的IP地址与自己不匹配后,就会直接将这个ARP请求报文丢弃。
需要注意的是,局域网当中其他不相干的主机在收到这个ARP请求报文后,不是在MAC帧层丢弃的,而是在ARP层发现该ARP数据包的目的IP与自己的IP不匹配后丢弃的。
总结:
- 发起方构建ARP请求,以广播的方式发送给每一个主机。
- 每台主机都能识别接收,然后根据MAC帧的帧类型字段将有效载荷交付给每个主机的ARP层。
- 其他不相关主机立马根据目的IP,在自己的ARP协议内部丢弃ARP请求,只有目标主机会处理请求。
ARP应答的过程
- 首先,因为主机D构建的是ARP应答,因此ARP应答当中的op字段设置为2。
- ARP应答当中的硬件类型、协议类型、硬件地址长度、协议地址长度的值与ARP请求当中设置的值相同。
- ARP应答当中的发送端以太网地址和发送端IP地址,对应的就是主机D的MAC地址和IP地址。
- ARP应答当中的目的以太网地址和目的IP地址,对应就是路由器J的MAC地址和IP地址,因为路由器J发来的ARP请求当中告知了主机D它的MAC地址和IP地址,因此主机D是知道的。
此时ARP应答构建完成,如下:
ARP应答构建完成后,为了能将ARP应答发送到以太网当中,也需要将ARP数据包向下交付给MAC帧,封装成MAC帧。
- 封装MAC帧报头时,以太网目的地址和以太网源地址,对应分别是路由器J和主机D的MAC地址。
- 因为这里封装的是一个ARP应答数据包,因此MAC帧当中的帧类型字段设置为0806.
- 由于ARP应答数据包的长度也只有28字节,不足46字节,因此也需要在MAC帧的有效载当中补上18字节的填充字段,最后再对MAC帧进行CRC校验。
此时ARP应答就被封装成MAC帧了,如下:
MAC帧封装完毕后,主机D就可以将封装好的MAC帧发送到局域网当中了。
- 此时局域网当中的每台主机在底层都能够接收到这个MAC帧,但局域网当中的不相干的主机,在发现该MAC帧对应的以太网目的地址与自己不同后,就会将该MAC帧丢弃,而不会交付给上层ARP层,最终只有路由器J会将解包后MAC帧的有效载荷向上交付给自己的ARP层。
- 当路由器J的ARP层收到这个数据包后,发现ARP数据包当中的op字段为2,于是判定这是一个ARP应答,然后就会提取出ARP数据包当中的发送端以太网地址和发送端IP地址,此时路由器J就拿到了主机D的MAC地址。
需要注意的是,局域网当中其他不相干的主机在收到这个ARP应答报文后,直接在MAC帧层就丢弃了,并没有将其交付给字节的ARP层。
ARP缓存表
- 需要注意的是,MAC帧和ARP虽然都在数据链路层,但毕竟是上下层关系,因此它们不会互相关心彼此报头当中的数据。
- 此外,如果底层网络采用的不是以太网,而是其他类型的网络,此时ARP层的MAC地址就是必要的了。
进行局域网通信时,为什么不直接以广播的方式发送数据?
理论上确实可以这样,但这种方式是不妥的。
- 对于局域网当中的大多数主机来说,收到的这个报文其实早就应该被丢弃,而现在这个报文却交付到了IP层,我们都知道IP层是属于操作系统管控的,因此这对网络资源和系统资源来说都是一种浪费。
- 因此在底层MAC帧层就应该判定这个报文是不是发送给当前主机的,而不是当数据向上交付到了IP层再来判断。
此外,如果无脑使用广播的方式来进行数据的发送,会使得广播和单播的概念变得模糊不清,你明白是想发送数据给局域网当中的一台主机,但你却采用了广播的方式,这显然是不合理的。
什么时候要发起ARP请求?
注意: ARP属于局域网通信的协议标准,因此一台主机不能跨网络向另一台主机发起ARP请求。
RARP协议