• 链路层


    链路层

    当数据从网络层发送下来, 又是如何定位到另一台主机或路由器中的呢?

    从之前的了解,不难发现,当数据从网络层发送时,此时我们指定了目的地的IP地址,并且无论是本机还是路由器都能够根据IP转发表决定我们将要发送的下一个端口是什么,该以哪一条链路进行发送。

    但在链路层呢?当脱离了IP地址,又如何从一端发送到另一端呢,在底层相互之间又是如何确定彼此的呢?

    在本篇中,仅仅就我个人比较感兴趣的知识点梳理总结一下。

    数据在何处发送

    在路由器中,链路层是在 线路卡中实现的, 而在主机中, 实现链路层的地方正是在 网络适配器, 也就是我们常常会听到的 网卡。

    在链路层是如何进行寻址的

    在链路层的寻址方式, 也就是链路层地址有各种不同的称呼: LAN地址,物理地址,或是最熟悉的 MAC地址。MAC地址长度为6字节, 即是2的48次方,对于每一台机器都有其全球独有的MAC地址,尽管MAC地址被设计成永久的, 但是通过软件修改MAC地址可能也是能够做到的。

    当某个适配器需要向目的适配器发送数据时,会将其目的地址的MAC地址插入到该帧中,并将该帧发送到局域网中。与网络层的概念类似,偶尔我们也会有发送广播数据给所有接口的需求,因此 一个适配器偶尔也会接收到 并不属于它自身的帧。

    此时,目的适配器会与自身的MAC地址相比较,如果是发送给它的,那么接收并解析数据。

    那如果我真的需要发送广播数据呢?

    此时,有类似于IP协议中的 255.255.255.255 广播地址 的 链路层地址, 即48个连续的1, 也即 FF-FF-FF-FF-FF-FF。

    那么问题来了。

    我怎么知道目的地的MAC地址是多少呢? 莫非我要存储全球的MAC地址? 还是像路由器那样配置相应的转发表?

    事实上是以这样的方式,转发这件事,还是交给网络层去做,在链路层只需要实现点对点的数据发送就可以了,即当我知道了我的下一跳IP是多少,那么我就已经知道我应该从哪个 接口 发送数据, 同时, 获取到下一跳IP地址所在路由器的MAC地址就可以了, 这样就将数据从主机发送到了路由器。

    至于以后?抱歉,我已经放在IP数据报中,请路由器你自己决定。

    那么如何知道下一跳, 也就是对应IP地址的MAC地址是多少呢?难道是在插入网线的时候由你主动告诉我吗?

    解决方式是ARP,我们已经知道通过DNS可以将域名解析为IP地址。不同的是 DNS是全球性的服务,而ARP只为在同一个子网中的路由器和主机提供服务。

    在每台主机或路由器中都保存着一个ARP表, 哎?等等, 这不还是通过表的方式存储起来了吗?那又费什么事呢?ARP是存储在内存中的,同时每条数据都有其失效时间,我们并不会无限制的保存相关的ARP表,过期就会删除。

    如果此时我要寻址的IP在ARP表中没有数据呢? 聪明的你一定想到了, 通过广播的方式, 告诉所有的相连主机,我需要知道IP地址为xxx的 MAC地址,请快速回复。

    而这,就是ARP协议, 首先,发送方构建一个ARP分组,一个ARP分组包含,发送和接收的IP地址和MAC地址。此时接收MAC地址自然为 FF-FF-FF-FF-FF-FF。接收到ARP分组的适配器将数据向上传递给ARP模块,这些ARP模块都检查,自己的IP地址是否与接收到的IP地址一致,如果一致,则响应, 将自身的MAC地址发送给对方。

    通过ARP已经解决了两个点之间的数据发送问题。

    以太网

    在发送端,控制器取得了存在协议栈较高层生成并存储在内存中的数据,在链路层帧中封装该数据报,填写该帧的各个字段,然后遵循链路层协议将数据发送到 通信链路中, 在接收端, 接收了整个帧,如果在链路层需要执行差错检验,则需要接收控制器执行差错检验, 之后提取出网络层数据报。

    以太网帧结构如下:

    前同步码:需要注意到的是即使没有数据需要发送, 根据以太网具体类型的不同也可能会发送IDLE, 也即一连串的11111, 在这里不太明白为什么要发送这些数据,可能因为在链路层数只有01两种数据形式,因此需要以1111来表示确定的IDLE状态, 其次, 在以太网间隙中发送的数据也都是111, 有了前导码,作用一是:告诉对方,我马上就要发送数据了,前导码的前7个字节目的是为了“唤醒”接收适配器,并将双方的时钟进行同步,而第八个自己的最后两个bit 则是告诉对方,数据即将到来。

    10101010 10101010 10101010 10101010 10101010 10101010 10101010 10101011

    目的地址:6 字节,这个字段是目的地的MAC地址,并不是指的最终的接收端,而是指当前接收以太网帧的路由器,交换机,自身的MAC地址,用这个地址来辨别数据究竟是否是发送给自己的,如果不是,也同样不是广播信息,则丢弃数据。

    源地址:6字节, 发送当前以太网帧的适配器。

    类型字段:2字节, 指定上层的协议类型,如IP协议 以及 刚刚提到的ARP协议。

    数据:数据这部分长度在 46~1500字节,最大传输单元在1500字节,至于为什么会有这样的最大最小值,稍后再提,如果不足46字节,会补全至46字节,所以以太网的上层协议, 最常用的是IP协议,需要在IP首部保存整个IP数据报的长度,以此来去掉以太网的填充部分。

    CRC:4字节,循环冗余校验, 目的是检验以太网帧中是否有差错。

    以太网与TCP有所不同, 是无连接服务, 也意味着如果需要发送数据,只要将数据进行封装处理, 直接发送给对方就可以了。同时, 如果发送过来的数据真的有误呢? CRC校验不通过, 并不会发送错误通知,成功了也不会有ACK信息,全部交由上层处理,如果上层是 IP UDP的方式, 这些数据丢失了就真的丢失了。

    46 1500

    参考:以太网数据帧(802.3)最大与最小长度

    要解决这个问题,需要一系列的其他知识来做补充。

    链路类型

    有两种类型的网络链路:广播链路和点对点链路,点对点链路由单一的发送方和接收方组成,点对点协议有PPP,HDLC等, 而广播链路则是让多个发送方和接收方都连接到相同的,单一的,共享的广播信道上,之所以说是广播,是因为当信道发送该帧,链路上的所有节点都会收到对应的副本,而以太网和无线网正是广播的典型例子。

    而就上述的概念来看,究竟该怎样协调各个节点之间的发送接收呢?广播信道只有一个,不可能让大家一起来说话,但事实上每个人都有说话的权力,那声音太乱,没有人可以听清究竟在说什么。

    而这就是多路访问问题。而计算机中的为了解决这个问题对应的则是 多路访问协议。

    即为了解决多个活跃节点在同一广播信道如何收发信息的问题。

    有以下几种类型的协议:

    • 信道划分协议

    • 随即接入协议

    • 轮流协议

    1. 信道划分协议

      信道划分协议的核心观点大概是这样, 有相应的 CDM TDM FDM几种技术做支撑, FDM频分多址技术,即大家沟通的时候,无需指定说话时间,每个人在每个时刻都可以发送信息,而通过 信息的 频率, 通俗来说,就是每个人说话的音色相差较大,计算机即能够识别这种音色,作为不同的数据源来对待。

      TDM则是将时间进行极细粒度的划分,约定好在某个时刻,由谁来进行说话。

      CDM码分多址,则是, 在每个帧的前面都加上前缀,表示信息来源是谁,这样即使收到一堆信息,也能够分别开来。主要是用在无线信道当中。

    2. 随即接入协议

      随即接入协议,是每个节点都以全速率发送该帧,当发生数据碰撞时,则重发该数据,直到数据通过为止。但并不是立即重发该数据,这个等待时间则是根据协议来确定。

      而常用的协议有 ALOHA 及 载波侦听多路访问协议(CSMA)协议。

      以太网正是一种 CSMA协议
      • ALOHA

        这种协议在每个时隙发送数据,如果此时冲突,则到下一个时隙继续以概率 P进行发送数据。通俗来讲是这样, 我们几个人同时开始讲话,我检测到了有人和我在一起说话,则在下一个时间点我掷硬币,硬币正面朝上的概率是P,如果正面朝上我说话,否则保持沉默。

        不难发现这样做会有大量的浪费,即使是在最优解的情况下 通讯节点数量一多, 其所能取到的效率 极值为 37%。

      • CSMA

        载波侦听多路访问, 即一个节点在传输之前先侦听信道, 如果此时有其他节点正在信道上发送消息,则等待,直到有一小段时间 没有信息发送,发送信息。 如果和别人一起发送信息了, 则停止发送消息,而后在重新侦听之前等待一段随机时间。

        但是我本身已经在侦听了, 又怎么会发生碰撞的事件呢? 这个的根本原因在于, 虽然发送消息的速率接近光速,但并不意味着消息从一个节点到达另一个节点之间的距离传播不需要时间, 这个就被成为信道传播时延。

      • 轮流协议

        轮流协议的一种实现方式是,轮询协议, 即存在主节点,循环告诉每个节点在当前时间所能发送的最大数据量,当当前节点发送完对应的数据之后, 继续询问下一个节点, 保证没有冲突存在。

    而发送最小字节的原因正是在这里, 如果数据足够小, 从远端节点A发送小数据 到 B, 此时B检测到冲突,将冲突信号发送给A, 当冲突信号到达A, 如果A的数据已经发送完毕, 此时它会误以为发送成功, 但事实上在B端, 检测到冲突,数据自然是发送失败的。 因此必须有最小帧长的限制, 有些设备发现达不到最小长度,会帮你填充无效数据到最小长度。

    至于具体的计算可以看: 传统 以太网 时隙(slot time) 理解

    根本目的则是,在碰撞信号到达A的时候, A的信号还没有发送完毕。而这个争用检测时间是 51.2微秒, 10M带宽在这个时间内能传输的数据量为 512bit 也即64字节。

    而除去以太网帧的固定格式,留给IP数据的最小长度就是46字节了。

    而1500字节,则是为了控制不能无限制的传输,占用所有的传输时间所定义的最大字节。

    链路层交换机

    同时也称作 二层交换机, 在实际中两台主机之间并不进行直连,而是通过交换机辅助发送。

    交换机工作流程如下:

    1. 当交换机从某个端口收到一个数据包,它先读取包头中的源MAC地址,这样它就知道源MAC地址的机器是连在哪个端口上的;
    2. 再去读取包头中的目的MAC地址,并在地址表中查找相应的端口;
    3. 如表中有与这目的MAC地址对应的端口,把数据包直接复制到这端口上;
    4. 如表中找不到相应的端口则把数据包广播到所有端口上,当目的机器对源机器回应时,交换机又可以学习一目的MAC地址与哪个端口对应,在下次传送数据时就不再需要对所有端口进行广播了。

    交换机自学习

    交换机表中,匹配的正是 MAC地址 和端 口, 同时还存在一个超时时间选项。

    我们假设一个以太网交换机有1、2、3、4,共4个接口,每个接口都分别连接了一台计算机,他们的MAC地址分别是A、B、C和D。在最开始的时候,交换机的交换表是空的。

    假如A向B发送了一帧,从接口1进入交换机,交换机收到这一帧之后会先查找交换表,不过很显然表是空的,交换机查不到应该从哪个接口转发这个帧(就是找不到目的地址为B的表项)。而后交换机会记录A的端口 MAC地址,记录时间。 而如果接口A将来被另一台主机占用,再发送消息的时候, MAC地址就会被替换掉。

    过了一段时间(老化时间)之后,交换机并没有收到源为 A的数据,就会将A对应的表项删除掉。

    如果找不到目的地址,则广播该帧。

    如果主机C收到了对应的消息, 发现目的地址并未自身的MAC地址,则会丢弃该数据。

    MAC欺骗

    这正是基于交换机自学习的一种有趣手段, 当我们发送数据,改变了自身的MAC地址为 B, 这样在交换机中就会记录, 通过MACB的接口 在 1, 这样就能够有效的将通往主机B的数据引导到1接口。使得B收不到数据。

    当然,如果B有发送消息的话,交换机依然会更新对应的数据。 此时需要发送源源不断的数据使得交换机表中数据一直更新。

    交换机毒化

    这同样是基于交换机学习机制的一个有趣手段,我们知道,当交换机表在表项中找不到对应的主机时,就会广播该帧。

    但事实是,交换机的表项存储空间是有限的,如果我们能够填满该空间, 此时交换机接收到的所有数据都会以广播的形式发送出来。

  • 相关阅读:
    如果一切需要重学,2014年应该学哪些技术?
    LINUX 更新
    LINUX学习
    判断设备是笔记本,还是台式机
    DUILIB 实现微信气泡聊天效果
    OC学习1
    DUILIB 背景贴图
    DUILIB CDialogBuilder 使用问题
    my english dream
    oracle 函数
  • 原文地址:https://www.cnblogs.com/zyzdisciple/p/11032207.html
Copyright © 2020-2023  润新知