目录
要解决的问题
以太网协议
以太网帧格式
MAC地址
MAC地址和IP地址
MTU
MTU对IP协议的影响
MTU对UDP协议的影响
MTU对TCP协议的影响
ARP协议
ARP协议格式
ARP协议的工作流程
ARP缓存表
要解决的问题
上一篇我们也说了,数据从应用层一步步封装到了网络层,网络层通过IP协议控制IP数据报如何转发,但是IP协议不能保证数据发送的可靠性,需要传输层来控制。
数据在网络中传输是需要路由的,通过路由表就可以一跳一跳地找到目的主机。首先就要解决的就是下一跳的问题,下一步该去哪。
我们也要知道的一点就是,数据下一跳的路由器和此时数据所在的机器是同一个局域网中的两台机器。
所以数据在网络中的路由策略IP协议已经做好了,将数据转发到下一个机器的动作就属于局域网通信了,这就是数据链路层要解决的问题。
以太网协议
不同的局域网所采用的技术可能是不同的,常见的局域网技术:
- 以太网:以太网是一种计算机局域网技术,也是最普遍的局域网技术。
- 令牌环网:令牌环网常用于IBM系统中,在这种网络中有一种专门的帧称为“令牌”,在环路上持续地传输来确定一个节点何时可以发送包。
- 无线LAN/WAN:无线局域网是有线网络的补充和扩展,现在已经是计算机网络的一个重要组织部分。
但是,不管局域网中采用哪种技术,对于网络层以上的结构都是不关心的,在数据路由的时候就可以根据哪种局域网添加哪种报头,最终都可以实现数据转发。
“以太网”不是一种具体的网络,而是一种技术标准,它既包含了数据链路层的内容,也包含了一些物理层的内容。例如,以太网规定了网络拓扑结构,访问控制方式,传输速率等。
以太网中的网线必须使用双绞线(可以理解为网线),传输速率有10M,100M,1000M等。
以太网帧格式
每一种协议都要解决的问题就是如何封装和解包并向上交付。
在局域网中转发时,也要标识主机的唯一性,使用的就是MAC地址,它是一个48位的整数,是在网卡生产时就已经内嵌在其中的一个固定序列,用来标识网卡的唯一性。
IP地址是网络层的概念,所以不想在数据链路层使用网络层的概念,要从软件上进行解耦。
目的地址表示要发送到哪一台主机,源地址表示从哪台主机发的。解包的过程也很简单,采用定长报头6 + 6 + 2字节,最后有一个CRC校验,也是固定长度4字节,头尾去除就是有效载荷。
在网络层向上交付时,IP报头中有8位协议字段,可以知道向上交付给传输层的哪个协议;传输层通过目的端口可以知道向上交付给应用层的哪个进程。那么数据链路层也要有这样的标识字段。类型字段中如果是0800就向上交付给IP协议。
如果在局域网中有许多主机,此时主机1要发送一个IP数据报给主机2,那么封装的MAC帧就类似于上图。当主机1发送MAC帧发送到局域网中,局域网中所有的主机都可以收到MAC帧,也包括发送端自己。
当主机收到MAC帧后,通过对比MAC帧中的目的地址,如果本机的MAC地址和目的地址相同,在CRC校验成功后就会把有效载荷交付给上层;如果MAC地址和目的地址不同就会直接丢弃这个MAC帧。
但是,这个局域网是公共的,肯定不止一台主机在发送MAC帧,其他主机也可能会发送,如果多台主机同时发送数据,数据之间就发生了碰撞问题,只要发生了碰撞问题,这个MAC帧就不能使用了,所以要避免发生碰撞问题,这就要有碰撞避免算法。
如果发生了碰撞,发送方肯定会知道的,之后他会休息随机时间,然后再重新发送。关于重新发送,那么数据链路层也要保证可靠性,发生了碰撞后过一段时间就重传;多台主机发送数据时,那么是不是在进行进程间通信,而进程间通信的本质就是让不同的进程看到同一份资源,那局域网被所有主机共享,那它就是一个共享资源。在碰撞检测时,发生了碰撞就重传,一定要保证在一个主机发送的时候,其他主机不能进行干扰,这就是独占某种资源,所以局域网资源本质上是一个临界资源。
那么局域网中的主机是越多越好还是越少越好?答案显而易见,那肯定是越少越好,主机越少,双方通信时收到的干扰就越小,发生碰撞的概率就越小,主机多了就是多台主机共享网络资源。
在局域网中还有一种设置就是交换机,它是工作在数据链路层的,交换机把局域网分为多个域,这就是划分碰撞域。
- 在同一个局域网中,如果一侧中的主机想要发送数据到另一侧,这两个主机不在同一个域中,那么就可以通过交换机把数据发送给对端。
- 如果同侧的域中两主机发送数据时,如果可以找到,交换机不会把数据发给另一侧,减少了两侧的压力
- 如果同侧的域发送数据时,域中发生了碰撞,交换机也不会把数据发给另一侧,避免垃圾数据发出。
MAC地址
关于MAC地址之前也说了,我们来看看Linux系统下的MAC地址,Ethernet就是以太网的意思,ether可以理解为MAC地址。
MAC地址和IP地址
数据在网络中路由过程中会存在两套地址,一套是源IP地址和目的IP地址,还有一套是源MAC地址和目的MAC地址。
- IP地址标明目的IP和源IP,由于NAT技术,源IP地址可能会变,但是目的地址是不变的。
- MAC地址标明目的MAC地址和源MAC地址,描述的是路由中的每个局域网转发的起点和终点。
MTU
MTU(Maximum Transmission Unit,最大传输单元)描述的是底层数据帧一次最多可以发送的数据量,这个限制是不同的数据链路层对应的物理层产生的。
而且转发数据的时候不能太多也不能太少。数据太多,发送的时间就会增加,碰撞几率也会增加,重发的成本也会增加;数据太少,发送的效率就会降低。
- 以太网帧规定数据的最小长度为46字节,如果发送数据量小于46字节,则需要在数据后面补填充位。
- 以太网对应MTU的值一般是1500字节,不同的网络类型有不同的MTU,如果一次要发送的数据超过了MTU,则需要在IP层对数据进行分片,不同的数据链路层标准的MTU是不同的。
MTU对IP协议的影响
由于MTU的限制,数据太大,IP协议就要对数据包分片,分片后才能向下交给数据链路层。
- IP协议会将超过MTU大小的数据进行分片,通过设置IP报头当中的16位标识、3位标志和13位片偏移来完成分片和组装。
- 对端网络层收到这些分片报文后,需要先将这些分片按顺序进行组装得到完整的IP数据报,之后再解包,向上交付给传输层。
- 如果分片后的某个分片在网络传输过程中丢了,那么对端在进行数据组装时就会失败,此时就需要传输层进行重传。
MTU对UDP协议的影响
如果传输层协议使用的是UDP,IP协议不携带选项,IP报头就是20字节,UDP报头就是8字节,如果UDP一次发送的数据超过1500 - 20 - 8 = 1472字节,IP协议就要进行分片。
- 只要有一个分片报文丢包了也就等同于这个报文整体丢失了。
- UDP协议不进行重传,这又大大增加了丢包的概率。
MTU对TCP协议的影响
如果传输层协议使用的是TCP,分片也会增加TCP报文丢包的概率,但与UDP不同的是,TCP丢包后还需要进行重传,所以也要减少因为分片导致的数据重传问题。
- TCP发送的数据段不能太大,我们将TCP的单个数据报的最大报文长度,称为MSS(Max Segment Size)。
- IP报头20字节,TCP报头20字节,并且不带选项,所以TCP发送数据不能大于1500 - 20 - 20 = 1460字节。所以为了不让网络层进行分片,规定MSS不能超过1460字节。
- 通信双方在建立连接的过程中,就会进行MSS协商,最终选取双方支持的MSS值当中的较小值作为最终MSS。
- MSS的值实际就是在TCP首部的40字节的选项字段中。
所以到这里我们才知道为什么网络层的分片不是主流。
ARP协议
ARP协议为地址解析协议(Address Resolution Protocol),是根据IP地址获取MAC地址的一个TCP/IP协议。
它存在的意义就是解决在局域网中,知道目的IP地址和源IP地址,知道源MAC地址,但是不知道目的MAC地址的问题。
TCP/IP模型中的数据链路层,其中有以太网协议我们已经知道了,但是这一层中还有ARP协议等其他协议,但是他们都属于数据链路层,只不过ARP协议在以太网协议的上一层。
ARP协议格式
现在我们只看28字节ARP报文。
- 硬件类型指链路层的网络类型,1为以太网。
- 协议类型指要转换的地址类型,0800为IP地址。
- 硬件地址长度对应以太网地址为6字节,因为MAC地址是48位的。
- 协议地址长度对应IP地址为4字节,因为IP地址是32位的。
- op字段为1表示ARP请求,op字段为2表示ARP应答。
ARP是MAC帧协议的上层协议,由于ARP数据包的长度不足46字节,因此ARP数据包在封装成为MAC帧时还需要补上18字节的填充字段。
ARP协议的工作流程
假设主机A需要向主机B发送数据,为了得知主机B也就是目的MAC地址,需要一方发起ARP请求。下面就是ARP请求的过程:
- 对于ARP报文的前4个字段都是差不多的,最重要的就是op字段,现在只知道发送端的MAC地址,发送端的IP地址和目的IP地址,不知道目的MAC地址就使用全F填充,使用这些字段填充ARP请求报文。
此时的ARP请求报文就是这样的:
ARP请求报文构建完成后,为了能将ARP报文发送出,还要封装成MAC帧:
- 封装MAC帧时,目的MAC地址和源MAC地址,对应分别是主机B和主机A的MAC地址,但是主机A不知道主机B的MAC地址,因此MAC帧报头当中的目的MAC地址的二进制序列也只能设置为全1,16进制就是全F,表示在局域网中进行广播。
- 此时的MAC帧类型就是0806了,表示这是一个ARP报文。
- 再添加填充字段和CRC校验就完成了。
MAC帧封装完成后就可以以广播的形式发送到局域网中。
- 每台主机都会收到这个MAC帧,然后对MAC帧进行解包,当识别到帧类型为0806后,知道了这是一个ARP报文,并向上交付给ARP层。
- 如果此时的ARP报文中的op字段为1,代表这是一个请求报文,再提取目的IP地址,整个局域网中只有主机B的IP地址与之匹配,其他的主机都会丢弃这个报文,所以检测IP地址是在ARP层执行的。
- 之后就是ARP应答的过程了。
此时的主机B已经收到了主机A的ARP请求,主机B要把自己的MAC地址发出,下面就是ARP应答的过程:
- 对于ARP报文的前4个字段都是差不多的,最重要的就是op字段,此时op就应该填2,源MAC地址和IP地址就是主机B的,目的MAC和IP地址就是谁向我请求的,就应答给谁。
此时的ARP响应报文就是这样:
ARP响应报文构建完成后,为了能将ARP报文发送出,还要封装成MAC帧:
- 封装MAC帧时,目的MAC地址和源MAC地址,对应分别是主机A和主机B的MAC地址。
- 此时的MAC帧类型就是0806了,表示这是一个ARP报文,不管是请求还是应答。
- 再添加填充字段和CRC校验就完成了。
MAC帧封装完成后就可以发送到局域网中。
- 此时局域网中的所有主机也收到了这个MAC帧,但是MAC帧的目的MAC地址是确定的,所以只有主机A会向上交付到ARP层,其他主机就会直接丢弃,所以这次的检测是在以太网层。
- 此时的ARP报文中的op字段为2,代表这是一个应答报文,至此主机A就拿到了主机B的MAC地址。
ARP缓存表
上面我们只是举了一个例子,实际的应用情况应该是这样的:
- 当我们使用自己的设备访问互联网中的服务器时,此时的请求报文已经到达了服务器机房的路由器中。
- 此时的报文只有目的IP地址,并没有目的MAC地址。
- 所以需要这个局域网中的路由器发送ARP请求,工作流程就是上面说的。
- 拿到目的MAC地址后,就可以封装完整的MAC帧,把数据转发给目标主机,再一层一层地向上交付。
这就有一个问题,是不是每次有从网络中来的报文都要做一遍ARP请求和响应呢?
答案显而易见,ARP请求成功后,请求方会暂时将IP和MAC地址的映射关系暂时保存起来。
还有一个点就是,这种请求和响应不仅仅发生在最后一跳,在路由的每一个过程中都会发生。每次发起ARP请求后都会建立对应主机IP地址和MAC地址的映射关系,每台主机都维护了一个ARP缓存表,可以用arp -a命令进行查看。
缓存表中是有时间限制的,这个时间一般为20分钟,如果20分钟内没有被使用,那么该映射就会失效,下次使用时就需要重新发起ARP请求来获得目的主机的MAC地址。