转载

[面试/网络] TCP/IP:数据链路层、IP协议以及IP协议相关技术

[面试/网络] TCP/IP:数据链路层、IP协议以及IP协议相关技术

[面试/网络] TCP/IP(一):数据链路层

背景

这一系列的文章主要是为一般的、非专业开发岗位(如移动端)的工程师准备,一方面可以对网络的基本知识有基本的了解,另一方面不至于面试中被问到相关问题时束手无策。知识以TCP/IP协议簇为主,也会有应用层和数据链路层的简单介绍。

文章内容不会很难,也不会过多讨论各种算法,目标是以最快的速度达到最深的理解。内容肯定比直接百度搜索“TCP/IP协议”,然后随便看一篇文章要丰富得多,但也不足以让读者凭此就可以胜任网络开发的工作。

诚然,面试以TCP/UDP/HTTP等协议为主,IP协议都涉及甚少,更遑论数据链路层等。但我希望可以从原理上理解那些问题,而不是临时抱佛脚,背了一些答案然后在面试后忘干净。不要为面试而准备面试,为了完善自己的知识体系而准备。如果你觉得这正是你需要的,Let's Begin!

OSI七层模型和协议

在这一节中,我们不谈这些层和协议的具体作用,目前只要知道OSI模型中,网络被分为七层,由底层向高层依次是:物理层,数据链路层,网络层,传输层,会话层,表示层和应用层。

协议是一个Big很高,出现很频繁的词。其实它很好理解,它实际上是一种通信双方共同遵守的规范。比如我需要把性别和年龄传递给另外一台主机,那么我可以定义一个"A协议",协议规定数据的前4个字节表示性别,后四个字节表示年龄。这样对方主机接收时就知道前4个字节是性别,而不会错把它当成年龄来处理。

整个互联网世界能够运行,完全得益于各个软件、硬件厂商严格遵守现有的协议。以IP协议为例,你可以随便修改它,然后自己弄出一个IP2协议,只不过没有人认可、遵守这个协议,所以它毫无用武之地。

物理层

物理层处于OSI七层模型的最低端,它的主要任务是将比特流与电子信号进行转换。

在计算机的世界中,一切都由0和1组成。你看到的这篇文章,在通过网络传输到你电脑的过程中,自然也是以0和1的形式存在。但是网络传输的介质(比如光纤,双绞线,电波等)中显然是不存在0和1的。比如在光线中,数据通过光的形式传递。0和1以光的亮灭表示,其中的转换由物理层完成。

如果没有物理层,由0和1构成的比特流就无法在物理介质中传播。

数据链路层

数据链路层处于OSI七层模型的第二层,它定义了通过通信介质相互连接的设备之间,数据传输的规范。

在数据链路层中,数据不再以0、1序列的形式存在,它们被分割为一个一个的“帧”,然后再进行传输。

数据链路层中有两个重要的概念:MAC地址和分组交换。

MAC地址

MAC地址是被烧录到网卡ROM中的一串数字,长度为48比特,它在世界范围内唯一(不考虑虚拟机自定义MAC地址)。由于MAC地址的唯一性,它可以被用来区分不同的节点,一旦指定了MAC地址,就不可能出现不知道往哪个设备传输数据的情况。

分组交换

分组交换是指将较大的数据分割为若干个较小的数据,然后依次发送。使用分组交换的原因是不同的数据链路有各自的最大传输单元(MTU: Maximum Transmission Unit)。不同的数据链路就好比不同的运输渠道,一辆卡车(对应通信介质)的载重量为5吨。那么通过卡车运送20吨的货物就需要把这些货物分成四部分,每份重5吨。如果运输机的载重量是30吨,那么这些货物不需要分割,直接一架运输机就可以拉走。

以以太网(一种数据链路)为例,它的MTU是1500字节,也就是通过以太网传输的数据,必须分割为若干帧,每个帧的数据长度不超过1500字节。如果上层传来的数据超过这个长度,数据链路层需要分割后再发送。

以太网帧

我们用以太网举例,介绍一下以太网帧的格式。

以太网帧的开头是“前导码(Preamble)”,长度为8字节,这一段没什么用,重点在于以太网帧的本体。

本体由首部,数据和FCS三部分组成:

[面试/网络] TCP/IP:数据链路层、IP协议以及IP协议相关技术

自学过程

类型部分存储了上层协议的编号,比如上层是IP协议,则编号为0800。

FCS表示帧校验序列(Frame Check Sequence),用于判断帧是否在传输过程中有损坏(比如电子噪声干扰)。FCS保存着发送帧除以某个多项式的余数,接收到的帧也做相同计算,如果得到的值与FCS相同则表示没有出错。

交换机

交换机是一种在数据链路层工作的网络设备,它有多个端口,可以连接不同的设备。交换机根据每个帧中的目标MAC地址决定向哪个端口发送数据,此时它需要参考“转发表”

转发表并非手动设置,而是交换机自动学习得到的。当某个设备向交换机发送帧时,交换机从帧的源MAC地址和接口对应起来,作为一条记录添加到转发表中。

下图描述了交换机自学过程的原理

[面试/网络] TCP/IP:数据链路层、IP协议以及IP协议相关技术

自学过程

关于数据链路层,最重要的一点还是它的定义:“过通信介质相互连接的设备之间,数据传输的规范”。这说明数据链路层的协议适用于处于同一种通信介质两端的节点。如果不能理解这一点,就无法理解网络层和IP协议。

数据链路层的意义在于,如果没有数据链路层,数据只能以流的形式存在与通信介质中,不知道该发送往哪里,过长的数据流可能无法在通信介质中传输。

[面试/网络] TCP/IP(二):IP协议

IP协议处于OSI参考模型的第三层——网络层,网络层的主要作用是实现终端节点间的通信。IP协议是网络层的一个重要协议,网络层中还有ARP(获取MAC地址)和ICMP协议(数据发送异常通知)

数据链路层的作用在于实现同一种数据链路下的包传递,而网络层则可以实现跨越不同数据链路的包传递。比如主机A通过Wi-Fi连接到路由器B,路由器B通过以太网连接到路由器C,而路由器C又通过Wi-Fi与主机D保持连接。这时主机A向D发送的数据包就依赖于网络层进行传输。

这篇文章主要介绍IP协议的基本知识和IP首部,IP协议可以分为三大作用模块:IP寻址、路由和IP分包。

IP地址

IP地址是一种在网络层用于识别通信对端信息的地址。它有别于数据链路层中的MAC地址,后者用于标识同一链路下不同的计算机。

举一个形象的例子,我要从镇江的家里去沈阳的东北大学,通信两端的地址分别是家和学校,他们相当于IP地址。然而没有交通工具可以让我从家直接去学校,所以我先要打车去火车站,然后坐高铁到沈阳站,再转公交去学校。这三次中转分别属于三种交通方式(数据链路),每一次中转都有起点和终点,他们就相当于MAC地址。每次中转可以称为一跳(Hop)

IP地址由32位正整数表示,为了直观的表示,我们把它分成4个部分,每个部分由8位整数组成,对应十进制的范围就是0-255。

比如172.20.1.1可以表示为:10101100 00010100 00000001 00000001。转换规则很简单,就是分别把四个部分的十进制(0-255)与8位二进制数字进行转换。

从功能上看,IP地址由两部分组成:网络标识和主机标识。

网络标识用于区分不同的网段,相同段内的主机必须拥有相同的网络表示,不同段内的主机不能拥有相同的网络标识。

主机标识用于区分同一网段下不同的主机,它不能在同一网段内重复出现。

32位IP地址被分为两部分,到底前多少位是网络标识呢?一般有两种方法表示:IP地址分类、子网掩码。

IP分类

IP地址分为四个级别,分别为A类、B类、C类和D类。分类的依据是IP地址的前四位:

A类IP地址是第一位为“0”的地址。A类IP地址的前8位是网络标识,用十进制标识的话0.0.0.0-127.0.0.0是A类IP地址的理论范围。另外我们还可以得知,A类IP地址最多只有128个(实际上是126个,下文不赘述),每个网段内主机上限为2的24次方,也就是16,777,214个。

B类IP地址是前两位为“10“的地址。B类IP地址的前16位是网络标识,用十进制标识的话128.0.0.0-191.255.0.0是B类IP地址的范围。B类IP地址的主机标记长度为16位,因此一个网段内可容纳主机地址上限为65534个。

C类IP地址是前三位为“110”的地址。C类IP地址的前24位是网络标识,用十进制标识的话192.0.0.0-239.255.255.0是C类IP地址的范围。C类地址的后8位是主机标识,共容纳254个主机地址。

D类IP地址是前四位为“1110”的地址。D类IP地址的网络标识长32位,没有主机标识,因此常用于多播。

子网掩码

IP地址总长度32位,它能表示的主机数量有限,大约在43亿左右。而IP地址分类更是造成了极大的浪费,A、B类地址一共也就一万多个,而世界上包含主机数量超过254的网段显然不止这么点。

我们知道IP地址分类的本质是区分网络标识和主机标识,另一种更加灵活、细粒度的区分方法是使用子网掩码。

子网掩码长度也是32位,由一段连续的1和一段连续的0组成。1的长度就表示网络标识的长度。以IP地址172.20.100.52为例,它本来是一个B类IP地址(前16位是网络标识),但通过子网掩码,它可以是前26为为网络标识的IP地址:

[面试/网络] TCP/IP:数据链路层、IP协议以及IP协议相关技术

子网掩码

路由控制

路由控制(Routing)是指将分组数据发送到目标地址的功能,这个功能一般由路由器完成。(不要与家里用的小型无线路由器混为一谈)

路由器中保存着路由控制表,它在路由控制表中查找目标IP地址对应的下一个路由器地址。下图描述了这一过程:

[面试/网络] TCP/IP:数据链路层、IP协议以及IP协议相关技术

路由控制

主机A的地址是10.1.1.30,要把数据发往地址为10.1.2.10的主机。在主机A的路由表中,保存了两个字段,由于目标地址10.1.2.10与10.1.1.0/24段不匹配,所以它被发往默认路由10.1.1.1也就是图中路由器1的左侧网卡的IP地址。

路由器1继续在它自己的路由控制表中查找目标地址10.1.2.10,它发现目标地址属于10.1.2.0/24这一段,因此将数据转发至下一个路由器10.1.0.2,也就是路由器2的左侧网卡的地址。

路由器2在自己的路由控制表中查找目标地址10.1.2.10,根据表中记录将数据发往10.1.2.1接口,也就是自己的右侧网卡的IP地址。主机B检查目标IP地址和自己相同,于是接收数据。

路由控制表

路由控制的关键在于路由控制表,路由控制表可以由管理员手动设置,称为静态路由控制,但是估计大部分人没这么干过。这是因为路由器可以喝其他路由器互换信息比即使自动刷新路由表,这个信息交换的协议并没有在IP协议中定义,而是由一个叫做“路由协议”的协议管理。

环路

上图中,假设主机A向一个不存在的IP地址发送数据,并且路由器1、2、3设置的默认路由形成了一个循环,那么数据将在网络中不断转发最终导致网络拥堵。这个问题将在下文分析IP首部时得到解决。

IP报文分割重组

在数据链路层中,我们已经提到过不同的数据链路有不同的最大传输单元(MTU)。因此IP协议的一个任务是对数据进行分片和重组。分片由发送端主机和路由器负责,重组由接收端主机负责。

路径MTU发现

分片会加重路由器的负担,因此只要条件允许,我们都不希望路由器对IP数据包进行分片处理。另外,如果一个分片丢失,整个IP数据报都会作废。

解决以上问题的技术是“路径MTU发现”。主机会首先获取整个路径中所有数据链路的最小MTU,并按照整个大小将数据分片。因此传输过程中的任何一个路由器都不用进行分片工作。

为了找到路径MTU,主机首先发送整个数据包,并将IP首部的禁止分片标志设为1.这样路由器在遇到需要分片才能处理的包时不会分片,而是直接丢弃数据并通过ICMP协议将整个不可达的消息发回给主机。

主机将ICMP通知中的MTU设置为当前MTU,根据整个MTU对数据进行分片处理。如此反复下去,直到不再收到ICMP通知,此时的MTU就是路径MTU。

以UDP协议发送数据为例:

[面试/网络] TCP/IP:数据链路层、IP协议以及IP协议相关技术

路径MTU发现

重组

接收端根据IP首部中的标志(Flag)和片偏移(Fragment Offset)进行数据重组。具体内容将在分析IP首部时详细解释。

IP首部(IPv4)

IP首部是一个有些复杂的结构,我们不用记忆它的结构,只需了解每个部分的作用即可,这样可以加深对IP协议的理解。

[面试/网络] TCP/IP:数据链路层、IP协议以及IP协议相关技术

IP首部

其中几个重要的部分介绍如下:

  • 总长度(Total Length):表示IP首部与数据部分总的字节数,该段长16比特,所以IP包的最大长度为65535字节(2^16)。虽然不同数据链路的MTU不同,但是IP协议屏蔽了这些区别,通过自己实现的数据分片功能,从上层的角度来看,IP协议总是能够以65535为最大包长进行传输。

  • 标识(ID:Identification):用于分片重组。属于同一个分片的帧的ID相同。但即使ID相同,如果目标地址、源地址、上层协议中有任何一个不同,都被认为不属于同一个分片。

  • 标志(Flags):由于分片重组,由三个比特构成。

第一个比特未使用,目前必须是0。

第二个比特表示是否进行分片,0表示可以分片,1表示不能分片。在路径MTU发现技术中就用到了这个位。

第三个比特表示在分片时,是否表示最后一个包。1表示不是最后一个包,0表示分配中最后一个包。

  • 片偏移(FO: Fragment Offset):由13比特组成,表示被分片的段相对于原始数据的位置。它可以表示8192(2^13)个位置,单位为8字节,所以最大可以表示8 x 8192 = 65536字节的偏移量。

  • 生存时间(TTL: Time To Live):表示包可以经过多少个路由器的中转。每经过一个路由器,TTL减1。这样可以避免前文提到的无限传递包的问题。

  • 协议: 表示IP首部的下一个首部属于哪个协议。比如TCP协议的编号为6,UDP编号为17.

  • 首部校验和:用于检查IP首部是否损坏

  • 可选项:仅在试验或诊断时用,可以没有。如果有,需要配合填充(Padding)占满32比特。

[面试?网络] TCP/IP(三):IP协议相关技术

在前两篇文章中,我分别介绍了数据链路层和网络层的IP协议。虽然这个系列教程的重点是搞定 TCP/IP,不过不用着急,本文简要介绍完与 IP 协议相关的技术,下一篇文章就会正式、详细的介绍 传输层与 TCP 协议。这篇文章会介绍 DNS、ARP、NAT 协议,这些内容虽然与 TCP 没有直接关联,但理解它们的原理有助于巩固基础知识,更好的理解网络的工作原理。

DNS 解析

IP地址用于识别通信双方的地址,但它是一串长数字,不方便记忆,人们希望主机有自己自己的名字,这个名字是唯一的,而且容易记住。于是,诞生了“域名”的概念。域名是一种为了识别主机名称和机构名的具有分层的名称,比如在域名 neu.edu.cn中,neu是主机名,edu 和 cn 是不同层次下的机构名。

域名和 IP 地址都可以唯一对应一台主机,DNS 协议的作用就是将自身具有意义的域名转换成不容易记住的 IP 地址。

域名是分层的,每层都有自己的 DNS 服务器用于处理 DNS 解析的请求。这样的好处在于每层的服务器不用关注过多的信息,它只要知道自己这一层下的域名服务器信息即可。以解析域名: www.ietf.org为例:

[面试/网络] TCP/IP:数据链路层、IP协议以及IP协议相关技术

DNS解析过程

根服务器其实并不知道 www.ietf.org 的 IP 地址,但是它知道 itef.org 服务器的地址,所以它把这条查询请求转发给 itef.org 服务器。DNS请求被逐层下发,直到找到对应的 IP 地址为止。

ARP 协议

ARP 协议(Address Resolution Protocol)用于通过目标 IP 地址,定位下一个接收数据包的网络设备的 MAC 地址。如果目标主机处在同一个数据链路上,那么可以直接得到目标主机的 MAC 地址,否则会得到下一条路由器的 MAC 地址。

ARP 协议的工作原理可以分为两部分:ARP 请求和 ARP 响应。 首先,目标主机会通过广播发送一个 ARP 请求包:“我要与 IP 地址为 xxx 的主机通话,谁知道它的 MAC地址?”。

数据链路上的所有主机都会收到这条消息并检查自己的 IP 地址,如果与 ARP 请求包中的 IP 地址一致,主机就会发送 ARP 响应包:“我就是 IP 地址为 xxx 的主机,我的 MAC 地址是:xxxx”。

下图表示了 ARP 协议的工作机制:

[面试/网络] TCP/IP:数据链路层、IP协议以及IP协议相关技术

ARP机制

在实际的使用过程中,每次往目标主机发送数据都要使用 ARP 是很低效的,通常的做法是把获取到的 MAC 地址缓存一段时间。一般来说,一旦源主机向目标地址发送一个数据包,接下来继续发送多次的概率非常大,因此这种缓存非常容易命中。

当下一次发送 ARP 请求或超过一定时间后,缓存都会失效,这保证了即使 MAC 地址与 IP 地址的对应关系发生了变化,数据包依然能够被正确的发往目标地址。

再次强调一下,MAC 和 IP 地址虽然看上去功能类似(都是用于唯一区分主机),但是两者缺一不可。如果只有 IP 地址,虽然可以跳过 ARP,直接在数据链路上发一个广播,但是这仅适用于通信双方处于同一个数据链路下的情况。如果双方处于不同的数据链路,数据报无法穿透中间的路由器。

如果全世界只用 MAC 地址,那么请参考交换机的自学过程,可以想象这个过程会带来庞大的,不必要的流量。

正因为 MAC 和 IP 地址缺一不可,所以才产生了 ARP 这样的协议将两者关联起来。

NAT 和 NAPT 技术

NAT (Network Address Translator) 是一种用于将局域网中的私有地址转换成全局 IP 地址的技术。

在连接上无线路由器的时候,如果检查一下设备的 IP 地址,也许你会发现是类似于 192.168.1.1 这样的局域网 IP 地址。那不同网段中,IP 地址都是 192.168.1.1 的主机改如何通信呢?

下图描绘了 NAT 的工作原理:

局域网中 IP 地址为 10.0.0.10 的主机向全局 IP 地址 163.221.174.37 发送数据。NAT 路由器将数据包的源地址修改成自己的全局 IP 地址:202.244.174.37。同理,接收数据时,路由器把目标地址 202.244.174.37 翻译成内网地址:10.0.0.10

[面试/网络] TCP/IP:数据链路层、IP协议以及IP协议相关技术

NAT工作原理

路由器只有一个对外的全局 IP 地址,如果有多个内网主机都向外部通讯怎么办呢?这时就要使用 NAPT 技术,它和 NAT 从原理上类似,但它可以转换 TCP 和 UDP 端口号。

使用 NAPT 技术时,不同的内网 IP 被转换成同一个公共 IP 地址,也就是路由器对外显示的全局 IP 地址,但是被附加不同的端口号以示区分:

[面试/网络] TCP/IP:数据链路层、IP协议以及IP协议相关技术

NAPT工作原理

不管是 NAT 还是 NAPT,都需要路由器路由器内部维护一张自动生成的地址转换表。以 TCP 为例,建立 TCP 连接首次握手的 SYN 包发出时会生成这个表,关闭连接时会发出 FIN 包,收到这个包的应答时转换表被删除。

如果暂时不了解 TCP 协议和三次握手也没有关系,下一篇文章将会有详细的讲解。

原文  http://www.cocoachina.com/programmer/20160225/15363.html
正文到此结束
Loading...