原文:https://www.jianshu.com/p/0e2d800b1520

术语

  • Nodes:主机和路由器
  • Links: 负责连接相邻两个节点的连接
  • 有线网
  • 无线网
  • 局域网
  • PACKets: frame(链路层对包的表述),它主要封装了上一层 datagram

每层的 Packet 形式

Packet 就是网络中传递的信息,但在不同层它会被封装成不同形式。下面举例了 3 层。

数据链路层和网络层(计算机网络:链路层)(1)

链路层是干什么用的

链路层是网络结构中的倒数第二层,最后一层是物理层,一般属于硬件部分,所以就从链路层开始说起。链路层提供了很多的服务(干了很多事)。

Framing

很重要的一个功能就是将上一层的 datagram (packet的一种形式) 封装成 frame。并在这个信息前后添加了 Header 和 Tailer。这里的 Header 一般包含了两台正在沟通设置的 Source 和 Destination 地址。

Link Access

既然是"链"路层了,肯定也要提供链接服务嘛。这一层主要提供两个:

  1. Point to Point,两台机器直接沟通
  2. Shared Medium,也就是我们所说的广播,一个人在微信群里喊

Flow Control

想像一下家里的水管,如果突然供水太多,那就爆水管了,网络也是这样。信息传递的时候需要用一些机制去控制传输速度。这个机制就叫 Flow Control,具体方法可以使用 Buffer 来做一个缓冲器。

Reliable Delivery

除了节流,这一层还负责保持信息的稳定传输。传个信怎么会出错呢?因为现在是在底层,所以很多因素都会影响传输质量,如信号干扰,网络不稳定。想一想平时有没有出现看视频掉帧的情况,还有耳机出现的噪音,这都是对信息传递干扰。所以链路层提供一些服务来保证传递质量,这些机制主要也是要使用于不同网络的如有线或者无线。

链路层在哪

说了一堆链路层的作用,好像太过抽象,不如说说具体位置。其实链路层在每台主机都有,它主要是在 Network Interface Card(NIC),也就是我们的网卡。

数据链路层和网络层(计算机网络:链路层)(2)

链路层的信息沟通

发送方

  1. 将 datagram 封装成 frame
  2. 添加 error bits, flow control, error recovery 等元信息

接收方

  1. 先看元信息,一然后做准备工作,如:如果发现错误就把这个包扔了,让发送方再发一次(retransmission)
  2. 然后将 frame 提取成 datagram,再向上传递

错误机制

就像刚刚说到的,传递信息过程中一定会出现错误的,链路层对此有两种机制:

  1. Error Detection
  2. Error Recovery

Error Detection

接收方会去检测错误率有多少,根据错误率去决定是否恢复数据还是让发送方重传。虽然说会检测错误,但是不是所有错误都能检测到的,有可能 miss 掉。其中EDC(Error Detection and Correction)越大,越容易检测到。

Error Recovery

错误恢复机制一般是两个

Correction

接收方会自己去改正对应错误的 Bits,但是需要大量的 EDC bits,才能做到 Correction,毕竟更多的信息才能正确去改正嘛。一般用于那些不想等待 retransmit 的数据

Retransmission

接收方会丢掉一些包,发送方就会重传。具体操作方法是直接超时,发送方得不到 ACK(就是一个接收完返回来的信号),发送方就得重传。或者,接收方直接发一个 Netgative ACK,发送方也得重传。

多路传输协议

不知道这让翻译对不对,英文是叫 Multiple access links protocol。在说这个协议有什么用之前,先说说以前的传输方式。

传输方式

  1. Point to Point,就是

发送方 <-> 接收方

,这和微信找好友聊天是一样的。一般是有线网络或者无线网络。 2. Broadcast,就是

发送方 <-> 多个接收方

,这和群聊是一样的。一般是WIFI或者老的以太网使用。

这个协议有什么用

上面说的两个传输方法都是在一个总线去完成消息传递的。所以总会出现同一个 Channel 中你在传数据的同时,别人也在传数据。不要想着什么多线程,这里只能一个一个来,所以就有了多路传输协议,主要是用于多人传的时候决定谁先传谁后传的问题,最后做出一个任务表出来。

有人一听到协议就不想看了,又要写 C,C 搞协议,好难啊。嘿嘿,其实这个协议主要理念特别智障,细节很难(也就是写C,C 那块,好在我们了解一下就行了)。常用的有:

  1. Channel Partitioning
  2. 将 Channel 分成更小块 (time slots, frequency, code)
  3. 分配某一块给那个节点使用
  4. Random Access
  5. 不分配,允许冲突
  6. 但是会在冲突以后进行恢复操作
  7. Taking Turns
  8. 节点会轮流发送信息,但是如果某个要发很多信息,就会占很长时间

CSMA

这里主要说说 Random Access 里的 CSMA 做法,为什么只拿这个来说呢,因为我们老师就讲了这个啊。

主要理念很简单:如果这个 Channel 空闲,我就传输,否则等到空闲再传。是不是很智障?听起来是的,细节反正不管了。

但是这个方法也有问题,如果两个节点特别远,自己想传数据的时候别人已经开始传了,但是因为太远了我没听见别人说"我开始传了,别人都不许动",还以为这个 Channel 还是空闲的,所以我传了数据,这就造成冲突。当冲突发生后,又要重传。可以我都把一个包的信息都发过去了呀,这整块时间就白白浪费掉了。

数据链路层和网络层(计算机网络:链路层)(3)

上面的交集部分就是冲突后浪费掉的时间。

CSMA/CD (Collision Detection)

这个算是增强版的 CSMA。以前的 CSMA 是两个人发完了再去重传,现在这个不一样了。在发送数据过程上,会去检测是否有冲突,如果有就放弃传输,等待下一次。毕竟还是要等一段时间才能检测出是否有冲突,所以依然有时间被浪费,但是会少一些。

数据链路层和网络层(计算机网络:链路层)(4)

关于怎么检测是否有冲突,可以检测信号的长度,对比传输和接收的信号(但是局限于距离和更小的 frame),可以在无线局域网比较难,接收信号距离太长。

下面再给出算法(算法???)的伪代码:

NIC 接收从网络层 datagram,并创建 frame label: step2 if (channel Idle): 开始传输 frame else if (channel busy): 等待直到 Idle if (检测是否有别的 transmission): abort wait K * 512 bit 的时间(K 是一个随机数) goto step2 else transmit

以太网

局域网里最出名也就是以太网了。电脑之间的联系基本为下面两种:

使用一条或几条总线。

数据链路层和网络层(计算机网络:链路层)(5)

或者一个主机,路由,现在一般是这种方式。

数据链路层和网络层(计算机网络:链路层)(6)

这里说一下 Switch 和 Hub 的区别。

  1. Switch: 节点传输不会有冲突,使用 Buffer 去做传输队列
  2. Hub: 每个节点会 Broadcast 信息,不使用 Buffer,有可能出现冲突

以太网的信息结构

我们知道在 HTTP 请求的时候总会有请求头,以太网的传输也是一样,也有头部信息。

数据链路层和网络层(计算机网络:链路层)(7)

preamble: 用来同步接收方和发送方的 Clock Rates addresses: Source 和 Destination 地址 type: 表示这个 frame 里最高层次是哪一层 CRC: 用于检测错误

以太网的特性

两个词:unreliable, connectionless

  • connectionless: 发送方和接收方没有握手流程
  • unreliable: 接收方的 NIC 不会发送 ACK 和 NACK
  • 如果数据被丢了就不会做恢复
  • 自己偷懒,更依赖于高层的数据传输

设备接口地址

啊,这是什么鬼东西,Device Interface Address 就是 IP 地址。

MAC 地址

我们可以会在家里的路由器看到这个词,MAC 地址就是该设备唯一的编号,IP 只是网络里的唯一编号。

这么说吧,IP 就像你的住址,你可以今天在北京买套房,你的IP就是北京了,明天去上海买套房搬去那边住,IP 就变成了上海。虽然说能变,但是你没有美国绿卡,再怎么变也不能逃不去中国,所以中国就是你所在的网络。说不定日本也有叫北京的地方,但是你们处于两个国家(两个网络),不会造成影响。

但是 MAC 就不一样了,就你的身份证一样,一直跟随着你。

ARP

那这个 MAC 有什么用呢?可以用来标记你在哪呀,别人发数据给你的时候是一定要不仅知道你的 IP,也要知道你的 MAC 的。你可能会问了,大哥我的 MAC 是写在路由器上的,难道你来我家看吗?电脑可不这么傻。

他会先广播一个叫 ARP 的请求,大概意思是:"那个XXX,给我出来!"。XXX 听到后就说:"我在YYY这呢,你有种过来干我。"。

再给个具体的鸽子:

比如 A 想发信息给 B,下面是前提条件

  1. B 一定要在同一个局域网里,而且 A 知道 B 的 IP
  2. A 不知道 B 的 MAC 地址

具体操作:

  1. 首先 A 在本地网络里去 Broadcast 一下,这个请求就是 ARP 请求包,其中包含了 B 的 IP
  2. 本地的全部节点都会接收到这个 ARP 请求,并处理
  3. 如果 B 此时也接收到这个请求,就会发 ARP replay 给 A,同时会带上 B' 的 MAC 地址。
  4. 这个过程都是在 Link Layer 完成的

数据链路层和网络层(计算机网络:链路层)(8)

每一次都要发太麻烦了,所以设备自己会做一张 ARP 表示,里面 IP 对应着已经知道的设备的 MAC 地址。ARP 表结构如下:

数据链路层和网络层(计算机网络:链路层)(9)

还有一些问题

问:如果给自己发 ARP 会怎么样? 答:不会怎么样,一般是没有响应罢了。不过这样可以检测同一个网络中是否存在别的主机的IP是否和自己一样。

问:如果给不存在的主机发 ARP 会怎么样? 答:也不会怎么样,最后就失败呗

,