透明的物理层和数据链路层
我们知道TCP/IP协议簇把网络划分为五层,第一层是物理层,第二层是数据链路层,但是实际上TCP/IP协议簇中并没有定义任何物理层和数据链路层的协议,也就是说所有物理层和数据链路层的协议都不属于TCP/IP协议簇。
这两层对TCP/IP协议来说是透明的,也就是说TCP/IP并不在意数据链路层和物理层是如何实现的,只要能按照预期传送数据即可(这就是编程中的解耦和内聚的思路啊)。
如果是这样的话,学习TCP/IP是不是没必要了解物理层和数据链路层?我认为并不是,物理层和数据链路层和网络的基础,了解实现原理对我们了解计算机网络是很有用的,可以了解到数据在底层是怎样被传输的。同时底层协议的一些设计也会影响到上层的协议,例如IP层的数据包大小限制等等。
物理层
在计算机网络中,物理层算是最具象化的一层了,很多东西都是我们能看得见摸得着的东西,例如网线、网口、交换机、路由器等等。
Tip
有人可能会说交换机明明是工作在数据链路层,路由器是工作在网络层,怎么就是物理层设备了?
这个问题还是比较好想清楚的,例如路由器可以连接网线,网线是工作在物理层的,路由器可以和网线通信,那么路由器肯定是可以工作在物理层的对吧?
物理层的职责
定义物理元器件
物理元器件例如:RJ45接口(网线插口)、水晶头、双绞线(网线)等等,所有这些元器件都需要有规范,厂商根据规范生产,这样才能保证兼容性。
调制和解调
这个好难。简单来讲,物理层只能传输电信号,计算机要发送的数据是连续的0和1
我们知道数据在计算机中的最终形态是0和1,在将数据发送出去的时候必须要转换成传输介质能传输的信号,例如双绞线可以传输的电信号,这个转换过程叫做调制;那么反过来,将电信号转换为计算机认识的数据的过程就叫做解调。
数据处理
我们知道物理层使用高低电平来传递信号,10101转换为电信号就是“高低高低高”,试想一下,如果传递的信号时1111111111呢?物理层如果连续发出10个高电平,那就相当于高电平连在一起了,怎么保证接收端收到的时10个1而不是9个或者11个呢?所以为了应对这个问题,物理层还需要使用一些其他的手段来解决这个问题。
- 编码:针对上面场景连续的1,我们可以在每个高电平上做一些变化,例如依次递增,这样接收端就可以清晰的识别到信号的边界,不会数错个数啦,这种编码方式叫做曼彻斯特编码;
- 时钟同步:举个例子,如果我们在10个连续的1后面插入一个信号,告诉接收端,你前面数完了10个数字,那这样接收端就一定不会数错了;
- 信号间隔:问题主要原因还是连续的1太多了,如果我们在中间插入间隔信号,不要让这么多连续的1在一起,那么问题就会得到比较大的缓解了;
上面只是举的一些例子,实际处理方法应该不会只有这些。
数据传输
物理层也要解决信号在传输过程中的问题。以双绞线为例,我们都知道导线都是由电阻的,电压在经过一段导线以后,一定会有所降低,如果高电平降低到了临界值,我们如何判断他是高电平还是低电平呢?
这实际上就是为什么网线不能拉太远的原因,如果非要拉的很远怎么办,第一可以换用更高规格的网线,更高规格的网线信号的损失会更小;第二使用中继器等工作在物理层的设备在中间对电信号做一次放大,这样信号就能传递到更远的地方了。
数据链路层
物理层解决了数据和电信号之间的转换问题、信号在介质中传输的问题,那么数据链路层在解决什么问题呢?
什么是数据链路
数据链路是一个逻辑概念,我总结了一下:当几台主机通过网线直接连接,或者通过工作在物理层或者数据链路层的设备连接在一起时,那么这几台主机就组成一个数据链路,他们在同一个数据链路内。
数据链路是网络的最小组成单元。
数据链路层的职责
数据链路层的职责就是保证在同一个数据链路内,数据能正确的送达到目标主机。
为了达到这个目的,数据链路层要解决下面的这几个问题:
- 主机的唯一地址,数据链路内的主机必须要有一个自己的唯一标识,这样我们才能分辨谁是谁,不至于把数据送错地方;
- 数据封装:数据包要封装成适合在线路上传输的大小然后再传输;
- 可靠传输:确保数据都发送出去了,确保接收端都收到了
- 传输介质管理,如果多台主机共用传输介质,路只有一条,谁先走谁后走,要商量着来;
MAC地址
数据链路层,为了解决主机唯一地址的问题,使用的是MAC地址。
MAC地址是主机在数据链路层的唯一标识。这个标识来源于网卡,是在网卡出厂的时候烧入ROM里面的,是硬件级别的地址,不可能发生改动的,就是网卡的身份证,任何一个网卡的MAC地址在全球都是唯一的(当然也有例外,例如虚拟机的MAC地址,但有一点,同一个网络内,MAC地址肯定是不重复的)。
MAC地址的定义
MAC地址总共使用6个字节标识,日常一般都使用16进制标识,并且2位一组,总共6组,使用短横线连接,示例如下:
拆开为2进制来看,结构是这样子的:
分为两大部分:
第一部分为厂商识别码,由IEEE颁发的厂商编号,IEEE保证此编号不重复,共占用3个字节;第二部分为厂商内编码,由厂商保证自己内部内部不重复。
在厂商识别码的第一个字节中有两位比较特殊,如图所示:
- 单播/广播标识,占1位,0为单播地址,1为多播地址;
- 全局/本地地址,占1位,0为全局地址,1为本地地址;
这两位IEEE分配的时候默认会是0。
了解完上述规格,应该非常容易理解MAC地址为什么不会重复了。
MAC地址的使用
下面我们来看看在数据链路内,消息是如何送到目标主机的:
数据链路内的每一台主机都会收到这个数据帧,他们会通过消息中设置的目标MAC地址来判断此数据帧是不是发送给自己的,如果是就接收,不是则丢弃。
Tip
图示是一个总线型网络,在当下的以太网,这种结构几乎不见了,但是为了说明在没有其他数据链路层设备参与的情况下,数据会怎么发送,所以用这个结构作为示例。
数据封装
在数据链路层,会把待发送的数据再包装一次,添加帧头和帧尾,变成一个数据帧,数据帧就是数据链路层最小的传输单位。以以太网为例,看看数据链路层的帧结构:
绿色部分是待发送的数据,橙色部分是数据链路层附加的数据,一起组成数据帧。数据链路层添加的数据主要是如下几个部分:
- 目标MAC地址和源MAC地址,用来识别数据帧的归属;
- Type记录上层协议的类型;
- Data是上层传递过来的待发送数据;
- FCS是校验和,用来校验Data有没有在传输中损坏;
Tip
数据链路层的帧封装格式并不只有一种,这里主要了解数据封装在做什么,所以只举了一个例子。
MTU
在上面的图里面,Data部分标记了一个范围是64~1500byte,这个值标识一个数据帧最大能携带的数据长度。
MTU(Maximum Transmission Unit) : 是指网络能够传输的最大数据包大小,以字节为单位,是属于数据链路层的属性。
为什么要限制一个数据帧携带数据的最大长度呢?如果待发送的数据是1MB,那岂不是要分很多个数据帧发送?一次性发送不是效率更高吗?
事实上,整包一起发送效率更高这种说法是没错的,毕竟拆分数据帧以后,一定会多出很多次的发送动作,同时每个数据帧都要添加数据链路层的帧头和帧尾,相当于加大了传输的数据量。
但是很多时候,我们往往无法追求极致的效率,只能在效率和性能直接做出一些取舍。
在当前的以太网中,接入的设备种类非常非常多,例如:个人电脑、大型服务器、路由器、交换机、手机等等,传输介质也多种多样,例如:网线、光纤、电磁波等等。各种设备对数据的处理能力不一样,各种介质传输的速度也千差万别,而且以太网上参与者众多,大家都在发送和接收数据。
- 网络设备层面来看,设备的处理能力是有限的,如果一个巨大的数据帧过来必定导致处理时间的增加,从而导致其他的数据帧无法得到及时的处理;
- 从传输介质的层面来看,传输介质在确定的时间内能通过的数据量是一定的,如果传输一个巨大的数据帧,传输的时间必定增加,如果数据帧的大小不可控,那么就无法在一个可预测的时间内到达目的地,无法控制超时;
- 从网络参与者的角度来说,由于传输介质的传输能力是一定的并且只能同时传输一个数据帧,如果当前在传输一个巨大的数据帧,那么其他的数据帧就必须等待这个数据帧传输完成,造成其他的数据帧延迟;
基于上述这些问题,所以我们必须要限制单个数据帧的大小,而这个数字在大多数设备中就是1500byte,加上数据链路层额外的帧头和帧尾,总共就是1518byte,如果超过这个大小,数据链路层就会拆分成多个数据帧发送,有些设备不具备拆帧能力的可能就会直接丢弃。
Tip
那最小64byte又是啥原因呢?如果待发送的数据没有64byte要怎么处理呢?
可靠传输
数据链路层的可靠传输并不是必要的,和网络类型有关系,例如在以太网协议种,并不需要数据链路层来保证可靠传输,会在更上层的协议来决定如何处理。而在PPP协议种,则是在数据链路层保证可靠传输,保证可靠传输的手段和TCP也非常类似;
- 错误检测,帧尾的FCS部分就是TCP中的校验和,就要确保帧数据没有出错;
- ACK和失败重传机制,来保证每一个数据帧都送达接收端;
- 帧序列号,用来给接收端标识帧的顺序;
- 流量控制:通过滑动窗口控制,和TCP类似;
传输介质管理
共享介质型网络
上图所示的这种网络连接类型叫做总线型,是共享介质型网络。这种连接方式是比较早期的以太网连接方式,但是现在基本已经很少见了。这种连接方式会有很多问题,例如:
- 一个数据帧,所有的主机都会收到,但是实际上只有一台是目标主机,这中间就会有很大的浪费;
- 一个数据链路内同时只能有一台主机在发送数据,其他主机都必须等着,所以在主机之间还必须协商介质的访问,效率也低;
Tip
这里所说的共享介质型网络的介质指的是传输介质,也就是网线,意思就是多台主机共用同一个传输介质。如果不同主机同一时间在同一条线路上发送电信号,那肯定就乱套了,所以还必须解决冲突。
所以在总线型网络中,要解决介质使用的问题,解决的方式有两种,一种是争用,一种是令牌传递。
总线型网络存在与同轴线时代,只能实现半双工通信,而且还要做介质访问控制,现在已经比较少见了。
Note
半双工通信指的是在同一时间内只能发送或者只能接收的通信方式,比较典型的例子就是对讲机;全双工通信指的是在同一时间内可以同时发送和接收,例如电话,可以两个人同时讲话。
非共享介质型网络
现代以太网的形态基本是这种星型结构,所有的主机都连接到交换机,通过交换机间接的连接到一起。使用的传输介质也从同轴线进化到了双绞线。
Tip
同轴线里面只有一根比较粗的线,所以很明显同一时间只能传递一个信号,最近见到的应该就是以前广电有线电视的线材,试想一下,有线电视是不是就是典型的半双工场景?双绞线里面一共4股共8根线,只需要对这8根线的功能进行定义,就能轻轻松松实现同时传递多个信号了。
星型网络结构的优点是:
- 不需要在做介质访问控制,数据可以直接发送;
- 主机基本不会再收到不属于自己的数据,因为数据由交换机分发,只会转发给对应的节点(当然也有例外,后面交换机的部分再细说);
但是星型网络也并不是全无缺点,例如:每个节点都必须连接到交换机,通过交换机交互数据,所以交换机就非常重要,如果交换机故障,会导致整个网络不可用;
工作在数据链路层的设备
交换机
上面说到的交换机,因为是工作在第二层(数据链路层),所以我们也叫他二层交换机。
Tip
我们常说的交换机就是二层交换机,也叫做网桥,两个网络之间的桥梁,很形象。也是集线器的一种,有交换功能的集线器就是二层交换机,可以同时工作在一层和二层;没有交换功能的集线器就叫集线器或者中继器(物理层时有说到),只工作在一层。
交换机的职责就很清晰了,接收主机发送过来的数据帧,转发给目标主机。
一般交换机还会有自学习的能力:
- 当交换机不知道网口关联的MAC地址时,它也只能把数据帧投递给所有非发送端的网口,这种发送方式叫做广播,广播能达到的链路就是这个数据链路的广播域;
- 同时它会把发送端的MAC地址和网口关联起来,下次如果有其他主机发送数据给这个MAC地址,那么交换机就会直接把数据帧投递到这个网口,这就是交换机的自学习能力。
Important
那么问题来了:通过交换机连接起来的主机,还在同一个数据链路中吗?
只要还在数据链路的广播域内,就可以认为是同一个数据链路。如果我们不考虑网络层的影响,我们可以认为交换机连接的主机还是在同一个数据链路内的。
数据链路层协议
上面一直在提到以太网,这里就说说以太网到底是什么?以太网和互联网到底是什么关系?忘了互联网是什么的话可以参考这里:网络的形态
以太网
以太网是数据链路层的一种网络协议,主要定义以下的内容:
- 帧格式,上面已经聊过了以太网定义的帧格式(以太网帧还有一个前导码,上面没有说到);
- 介质访问控制方式(在共享介质型网络中);
- 网络拓扑,总线型,星型等等;
- 错误检查(使用FCS实现);
- 物理层规范,例如传输介质,信号特性等;
Note
有些数据链路层协议会定义物理层的规范,而有一些不会,例如以太网就定义了一些物理层规范,但是PPP就没有。
这样看下来,以太网和互联网是完全属于不同的层次对网络的分类。互联网描述的是网络连接的范围。以太网描述的是局域网内,数据链路层使用的是什么协议。
PPP和PPPoE
数据链路层协议很多,这里无法一个个讲清楚(关键是不懂),再说一个经常会遇到的。
PPP(Point-to-Point Protocol)是指点对点协议,即1对1连接计算机的协议,PPP协议经常会用在身份验证中。这个协议日常生活中可能见的少,但是PPPoE可能很多人或多或少听说过一些,经常用在家用宽带拨号上网中。
PPPoE全称是PPP over Ethernet,家用网络通常都是以太网(毕竟设备线路都便宜),但是以太网没有鉴权,也没有连接和断开,如果直接使用以太网连接,那我们只需要把自己的网线插到服务商的路由器上就可以上网了。但是宽带服务商也是要吃饭的,必须交了钱才给服务,所以要想办法区分出那些交了钱和没交钱的。
怎么区分呢?解决的方法就是鉴权,相当于给每个数据帧一个身份,识别到是从哪里来的,是否有“通行证”,使用的就是PPPoE协议。我们来看看PPPoE在家用宽带场景是怎么解决这个问题的:
拨号
- 我们在路由器上填好用户名密码,发起拨号,路由器发送一个PPPoE的拨号请求;
- 在拨号阶段,PPPoE服务端会通过PPP协议完成身份验证,确保用户的合法性;
- 拨号成功后,即建立连接,这个连接的状态维护在PPP协议中处理;
数据发送
- 上层数据来到数据链路层,首先使用PPP协议封装,这样数据就有了鉴权状态;
- 然后PPP数据帧在使用PPPoE封装进自己的帧头;
- 最后PPPoE数据帧再使用以太网协议封装成以太网帧,最后发送出去;
最终发送出去的数据帧就变成这样了:
上面已经讨论过了,以太网帧要保持Data最大为1500byte,现在又多包装了两层协议进去,多占用了10byte,所以携带的有效数据就变成了1490byte,上层协议如果不希望出现拆帧,那么如果数据链路层是PPPoE,就要控制字节的数据大小不超过1490byte.
Tip
这里写的不太详细,先这样吧,下次有机会再来补充细节。
总结
物理层和数据链路层肯定远不止上述这些内容,主要还是在围绕以太网相关的实现在描述,为的是后面很好的了解后面的TCP/IP协议。
关联:
TCP/IP协议系列之网络基础