三、mac头部 四、何为以太网 1.以太网的定义 2.如何收发以太网包 3.以太网接收网络包详细 4.收到网络包后,协议如何工作 一、以太网包 TCP 模块在执行连接、收发、断开等各阶段操作时,都需要委托IP 模块...
目录
TCP模块在执行连接、收发、断开等各阶段操作时,都需要委托IP模块将数据封装成包发送给通信对象。我们在TCP的讲解中也经常提到IP, 下面就来讨论一下 IP模块是如何将包发送给对方的。正式开始这个话题之前,我们先来介绍一下关于网络包的一些基本知识。
首先,包是由头部和数据两部分构成的(图a)。头部包含目的地址等控制信息,大家可以把它理解为快递包裹的面单;头部后面就是委托方要发送给对方的数据,也就相当于快递包裹里的货物。一个包发往目的地的过程如图所示。 首先,发送方的网络设备会负责创建包,创建包的过程就是生成含有正确控制信息的头部,然后再附加上要发送的数据。接下来,包会被发往最近的网络转发设备。当到达最近的转发设备之后,转发设备会根据头部中的信息判断接下来应该发往哪里。这个过程需要用到一张表,这张表里面记录了每一个地址对应的发送方向,也就是按照头部里记录的目的地址在表里进行查询,并根据查到的信息判断接下来应该发往哪个方向。
具体来说,如图(b)所示,TCP/IP包包含如下两个头部。
(a)MAC头部(用于以太网协议)
(b)IP头部(用于IP协议)
比如,如果查表的结果是“目标地址为××××的包应该发到××××号线路”,那么转发设备就会把这个包发到××××号线路去。接下来,包在向目的地移动的过程中,又会到达下一个转发设备,然后又会按照同样的方式被发往下一个转发设备。就这样,经过多个转发设备的接力之后,包最终就会到达接收方的网络设备。当然,发送方向接收方发送一个包,接收方可能也会向发送方返回一个包,此时的发送方到了接下来的某个时刻就会变成接收方。因此,我们不需要把发送方和接收方明确区分开来,在这里我们把发送方和接收方统称为终端节点。
前面介绍的这些基本知识,对于各种通信方式都是适用的,当然也适用于 TCP/IP网络。不过,TCP/IP包的结构是在这个基本结构的基础上扩展出来的,因此更加复杂。在其他《网络知识入门》中讲过子网的概念,还讲过网络中有路由器和集线器两种不同的转发设备,它们在传输网络包时有着各自的分工。
(1)路由器根据目标地址判断下一个路由器的位置
(2)集线器在子网中将网络包传输到下一个路由
实际上,集线器是按照以太网规则传输包的设备,而路由器是按照IP规则传输包的设备,因此我们也可以作如下理解。
(1)IP协议根据目标地址判断下一个IP转发设备的位置
(2)子网中的以太网协议将包传输到下一个转发设备
首先,发送方将包的目的地,也就是要访问的服务器的 IP地址写入IP头部中。这样一来,我们就知道这个包应该发往哪里,IP协议就可以根据这一地址查找包的传输方向,从而找到下一个路由器的位置,也就是下图中的路由器R1。
接下来,IP协议会委托以太网协议将包传输过去。这时,IP协议会查找下一个路由器的以太网地址(MAC地址),并将这个地址写入MAC头部中。这样一来,以太网协议就知道要将这个包发到哪一个路由器上了。
网络包在传输过程中(图2.16①)会经过集线器,集线器是根据以太网协议工作的设备。为了判断包接下来应该向什么地方传输,集线器里有一张表(用于以太网协议的表),可根据以太网头部中记录的目的地信息查出相应的传输方向。这张图中只有一个集线器,当存在多个集线器时,网络包会按顺序逐一通过这些集线器进行传输。 接下来,包会到达下一个路由器(图②)。路由器中有一张IP协议的表,可根据这张表以及IP头部中记录的目的地信息查出接下来应该发往哪个路由器。为了将包发到下一个路由器,我们还需要查出下一个路由器的 MAC地址,并记录到MAC头部中,大家可以理解为改写了MAC头部。这样,网络包就又被发往下一个节点了。 再往后的过程图上就没有画出来了。网络包会通过路由器到达下一个路由器 R2。这个过程不断重复,最终网络包就会被送到目的地,当目的地设备成功接收之后,网络包的传输过程就结束了。
前面介绍的就是在 TCP/IP网络中,一个网络包从出发到到达目的地的全过程。虽然看起来有点复杂,不过设计这样的分工是有原因的。前面讲了IP和以太网的分工,其中以太网的部分也可以替换成其他的东西,例如无线局域网、ADSL、FTTH等,它们都可以替代以太网的角色帮助IP协 议来传输网络包。因此,将IP和负责传输的网络分开,可以更好地根据需要使用各种通信技术。像互联网这样庞大复杂的网络,在架构上需要保证灵活性,这就是设计这种分工方式的原因。

二、协议栈中IP模块的工作方式

1.TCP委托IP模块

尽管我们说IP模块负责将包发给对方,但实际上将包从发送方传输到接收方的工作是由集线器、路由器等网络设备来完成的,因此IP 模块仅仅是整个包传输过程的入口而已。即便如此,IP模块还是有很多工作需要完成,首先我们先粗略地整理一下。
包收发操作的起点是 TCP 模块委托 IP 模块发送包的操作(图“①发送”)。这个委托的过程就是 TCP 模块在数据块的前面加上 TCP 头部,然后整个传递给 IP 模块,这部分就是网络包的内容。与此同时,TCP 模块还需要指定通信对象的IP地址,也就是需要写清楚“将什么内容发给谁”。收到委托后,IP模块会将包的内容当作一整块数据,在前面加上包含控制信息的头部。刚才我们讲过,IP模块会添加IP头部和MAC头部这两种头部。IP头部中包含IP协议规定的、根据IP地址将包发往目的地所需的控制信息;MAC 头部包含通过以太网的局域网将包传输至最近的路由器所需的控制信息。加上这两个头部之后,一个包就封装好了,这些就是IP模块负责的工作。
接下来,封装好的包会被交给网络硬件(图②发送),例如以太网、无线局域网等。网络硬件可能是插在计算机主板上的板卡,也可能是笔记本电脑上的 PCMCIA卡,或者是计算机主板上集成的芯片,不同形态的硬件名字也不一样,我们在这里称为网卡。传递给网卡的网络包是由一连串 0和1组成的数字信息,网卡会将这些数字信息转换为电信号或光信号,并通过网线(或光纤)发送出去,然后这些信号就会到达集线器、路由器等转发设备,再由转发设备一步一步地送达接收方。包送达对方之后,对方会作出响应。返回的包也会通过转发设备发送回来,然后我们需要接收这个包。接收的过程和发送的过程是相反的,信息先以电信号的形式从网线传输进来,然后由网卡将其转换为数字信息并传递给 IP模块(图③接收)。接下来,IP模块会将MAC头部和 IP头部后面的内容,也就是TCP头部加上数据块,传递给TCP模块。接下来的操作就是我们之前讲过的TCP模块负责的部分了。在这个过程中,有几个关键的点。TCP模块在收发数据时会分为好几个阶段,并为各个阶段设计了实现相应功能的网络包,但IP的包收发操作都是相同的,并不会因包本身而有所区别。因为IP模块会将TCP头部和数据块看作一整块二进制数据,在执行收发操作时并不关心其中的内容,也不关心这个包是包含 TCP头部和数据两者都有呢,还是只有TCP头部而没有数据。当然,IP模块也不关心TCP的操作阶段,对于包的乱序和丢失也一概不知。总之,IP 的职责就是将委托的东西打包送到对方手里,或者是将对方送来的包接收下来,仅此而已。因此,接下来我们要讲的这些关于 IP的工作方式,可适用于任何TCP委派的收发操作。
IP 模块负责添加如下两个头部。
(1)MAC 头部:以太网用的头部,包含 MAC 地址
(2)IP 头部:IP 用的头部,包含 IP 地址

2.IP模块的工作方式

下面来看一看IP模块的具体工作过程。IP模块接受TCP模块的委托负责包的收发工作,它会生成IP头部并附加在TCP头部前面。IP头部包含的内容如下表所示,其中最重要的内容就是IP地址,它表示这个包应该发到哪里去。这个地址是由TCP模块告知的,而TCP又是在执行连接操作时从应用程序那里获得这个地址的,因此这个地址的最初来源就是应用程序。

字段名称长度(比特)含义
版本号
4
IP 协议版本号
头部长度(IHL)
4
IP 头部的长度。可选字段可导致头部长度变化, 因此这里需要指定头部的长度
服务类型(ToS)
8
表示包传输优先级。最初的协议规格里对这个参 数的规定很模糊,最近 DiffServ 规格重新定义了
这个字段的用法
总长度
16
表示 IP 消息的总长度
ID 号
16
用于识别包的编号,一般为包的序列号。如果一个包被 IP 分片,则所有分片都拥有相同的 ID
标志(Flag)
3
该字段有 3 个比特,其中 2 个比特有效,分别代表是否允许分片,以及当前包是否为分片包
分片偏移量
13
表示当前包的内容为整个 IP 消息的第几个字节
开始的内容
生存时间(TTL)
8
表示包的生存时间,这是为了避免网络出现回环时一个包永远在网络中打转。每经过一个路由器, 这个值就会减 1,减到 0 时这个包就会被丢弃
协议号
8
协议号表示协议的类型(以下均为十六进制)。
TCP: 06
UDP: 11
ICMP: 01
发送方 IP 地址
32
网络包发送方的 IP 地址
接收方 IP 地址
32
网络包接收方的 IP 地址
可选字段
可变长度
除了上面的头部字段之外,还可以添加可选字段用于记录其他控制信息,但可选字段很少使用

IP不会自行判断包的目的地,而是将包发往应用程序指定的接收方,即便应用程序指定了错误的IP地址,IP模块也只能照做。当然,这样做肯定会出错,但这个责任应该由应用程序来承担。IP 头部中还需要填写发送方的IP地址,大家可以认为是发送方计算机的IP地址,实际上“计算机的IP地址”这种说法并不准确。一般的客户端计算机上只有一块网卡,因此也就只有一个IP地址,这种情况下我们可以认为这个 IP地址就是计算机的IP地址,但如果计算机上有多个网卡, 情况就没那么简单了。
IP地址实际上并不是分配给计算机的,而是分配给网卡的,因此当计算机上存在多块网卡时,每一块网卡都会有自己的IP地址。很多服务器上都会安装多块网卡,这时一台计算机就有多个IP地址,在填写发送方 IP地址时就需要判断到底应该填写哪个地址。这个判断相当于在多块网卡中判断应该使用哪一块网卡来发送这个包,也就相当于判断应该把包发往哪个路由器,因此只要确定了目标路由器,也就确定了应该使用哪块网卡,也就确定了发送方的IP地址。那么,我们应该如何判断应该把包交给哪块网卡呢?
这就涉及一个叫做路由表的概念。因为协议栈的IP 模块与路由器中负责包收发的部分都是根据 IP协议规则来进行包收发操作的,所以它们也都用相同的方法来判断把包发送给谁。 这个“IP表”叫作路由表,如下图所示,我们可以通过route print
(windows)命令来显示路由表,下面来边看边讲。
首先,我们对套接字中记录的目的地 IP地址与路由表左侧的Network Destination栏进行比较,找到对应的一行。例如,TCP模块告知的目标IP地址为192.168.1.21,那么就对应图中的第6行,因为它和192.168.1的部分相匹配。如果目标IP地址为 10.10.1.166,那么就和10.10.1的部分相匹配,所以对应第3行。以此类推,我们需要找到与IP地址左边部分相匹配的条目B,找到相应的条目之后,接下来看从右边数第2列和第3列的内容。右起第2列,也就是Interface列,表示网卡等网络接口,这些网络接口可以将包发送给通信对象。此外,右起第3列,即Gateway列表示下一个路由器的IP地址,将包发给这个IP地址,该地址对应的路由器就会将包转发到目标地址。路由表的第1行中,目标地址和子网掩码都是0.0.0.0,这表示默认网关,如果其他所有条目都无法匹配,就会自动匹配这一行。
这样一来,我们就可以判断出应该使用哪块网卡来发送包了,然后就可以在IP头部的发送方IP地址中填上这块网卡对应的IP地址。接下来还需要填写协议号,它表示包的内容是来自哪个模块的。例如, 如果是 TCP模块委托的内容,则设置为06(十六进制),如果是UDP模块委托的内容,则设置为17(十六进制),这些值都是按照规则来设置的。在现在我们使用的浏览器中,HTTP请求消息都是通过TCP来传输的,因此这里就会填写表示 TCP的06(十六进制)。

三、mac头部

生成了IP头部之后,接下来IP模块还需要在IP头部的前面加上MAC 头部(如表所示)。IP头部中的接收方IP地址表示网络包的目的地,通过这个地址我们就可以判断要将包发到哪里,但在以太网的世界中,TCP/IP 的这个思路是行不通的。以太网在判断网络包目的地时和 TCP/IP 的方式不同,因此必须采用相匹配的方式才能在以太网中将包发往目的地,而MAC 头部就是干这个用的。

字段名称长度(比特)含义
接收方 MAC 地址
网络包接收方的 MAC 地址,在局域网中
使用这一地址来传输网络包
发送方 MAC 地址
网络包发送方的 MAC 地址,接收方通过
它来判断是谁发送了这个包
以太类型
使用的协议类型。下面是一些常见的类型,
一般在 TCP/IP 通信中只使用 0800 和0806
这两种。
0000-05DC:IEEE 802.3
0800 :IP 协议
0806 :ARP 协议
86DD IPv6

IP 模块在生成IP头部之后,会在它前面再加上MAC头部。MAC头部是以太网使用的头部,它包含了接收方和发送方的MAC地址等信息。 关于以太网的结构我们稍后会进行介绍,但下面的内容需要一些MAC 头部的相关知识才能理解,因此先介绍一些最基础的。
MAC头部的开头是接收方和发送方的 MAC地址,大家可以认为它们和IP头部中的接收方和发送方IP地址的功能差不多,只不过IP地址的长度为32比特,而MAC地址为 48比特。此外,IP地址是类似多少弄多少号这种现实中地址的层次化的结构,而MAC地址中的48比特可以看作是一个整体。尽管有上述差异,但从表示接收方和发送方的意义上来说,MAC地址和IP地址是没有区别的,因此大家可以暂且先把它们当成是一回事。
第3个以太类型字段和 IP头部中的协议号类似。