网络那些事儿3-IP数据包相关知识

上一节讲了网络中数据收发的流程,从总体上了解了数据在网络中的传输过程,这一节我们深入网络数据收发的细节,从网络中数据传输的基本数据包讨论一下IP模块是怎么将数据发送出去的。

IP包的基础知识

网络中数据的传递都是以网络包的形式进行的,数据在被传递到网络上之前都会在本地被网络协议栈封装成符合网络规范的网络包,然后才传递到网络。

网络包的具体形式是什么样的呢?如下图所示

网络包由头部和数据内容两部分组成,其中头部是有多个网络协议栈头部组成,包括MAC头部、IP头部、TCP头部等内容,数据内容就是我们要在网络中传递的数据信息,需要注意的是这个数据内容是符合网络数据格式的内容,并非我们通常使用的字符串等数据格式的内容。

数据发送方由本机创建网络包,创建网络包的过程就是生成含有正确头部信息的头部,然后附加上要发送的数据,然后发送给最近的网络转发设备比如路由器,然后路由器根据头部信息判断接下来应该发送到哪里,这里路由器是根据路由表来决定数据包的去向的,接下来数据包被转发到下一个转发设备,根据相同的原理再次被转发,直到到达最终目的地。

以TCP/IP为例,TCP/IP的网络包是在基本结构的基础之上扩展而来的,更加复杂一些,如下图所示

MAC头部用于以太网协议,IP头部用于IP协议,之前我们说到网络中的设备包含有集线器和路由器,集线器用于将网络包传输到下一个路由器,路由器用于判断下一个路由器的位置,而MAC头部在集线器将网络包传输到下一个路由器的过程作为集线器提供一些控制信息,使其能够正确发送出去,IP头部则是在路由器转发的时候提供一些控制信息使其能够正确转发出去。这里需要说明一下的是,网络包的构建过程是先创建一个包含TCP头部信息的网络包,然后将数据信息填入,再块封装一个IP头部,然后再封装一个MAC头部。

网络包在传输过程中经过集线器时,集线器根据以太网协议以及网络包内的MAC头部信息判断这个网络包接下来应该往什么方向传输,集线器内也有一张表,能够根据头部信息查询出相应的传输方向。当需要经过多个集线器时,网络包会逐一通过这些集线器进行传输。

当网络包经过集线器后到达路由器时,路由器根据网络包内的IP头部信息判断接下来这个网络包应该被转发到哪里,并且会查询出下一个转发路由的MAC地址填写到这个网络包的MAC头部中,可以认为是修改了这个网络包的MAC头部信息。如果需要经过多个路由器,那么网络包会根据上面的流程依次经过这些路由器,最终网络包被送到目的地,传输过程就结束了。

以太网数据传输是分工合作的方式进行的,分为IP和以太网传输,这样设计网络传输是有原因的,以太网部分可以替换成无线局域网、ADSL、FTTH等,他们可以替换以太网的角色帮助IP协议来传输网络包,这样我们就可以根据需求使用不同的通信技术结合IP协议来传输数据,具有更多的灵活性,这就是分工设计的原因。网络传输

数据包收发

IP模块负责将网络包发送出去,这里说的发送出去仅仅是指从本级的网卡设备通过网线发送出去,网络包要想到达目的地址,还需要路由器、集线器等不同的网络设备通力协作才能完成,因此,IP模块在整个网络包的传输过程中相当于一个入口的作用。但是入口内部的功能还是通过的,下面大致说一下。

网络包最初的起点是TCP模块创建的,TCP模块创建完委托IP模块进行发送,委托的过程就是在TCP创建的数据块前加入TCP头部信息,然后将这个网络包传递给IP模块。IP模块收到TCP的委托后,IP模块会将包含TCP头部信息的数据块当作一个整体,这里我们成为TCP网络包,IP模块会在TCP网络包前面增加包含控制信息的IP头部和MAC头部,其中IP头部 包含发往目的地之所需的控制信息,MAC头部包含通过以太网的局域网包传输至最近的路由器所需的信息,加上这两个头部后,一个完整的网络包就封装好了,这就是IP模块的工作。

接下来封装好的网络包会被交给硬件设备,比如计算机的网卡,IP模块会讲网络包转化为对应的0和1组成数字信息,然后由网卡将这些数字信息转化为电信号或关心好通过网线或光纤发送出去,这些信号到达集线器、路由器后,在一步步转发到达接收方。数据到达接收方后,作出的响应通过与刚才相反的过程到达发送方,这时发送就变成了数据的接收方。数据信息先以电信号或光信号的形式传递过来,网卡接收响应的数字信息(即0和1组成的信息),交给IP模块转化为我们常用的数据格式,IP模块会将MAC头部和IP头部后面的内容,也就是TCP头部和数据块传递给TCP模块。

MAC头和IP头部具体内容

自行google。-_-

这里需要说明一下的是接收方MAC地址查询,我们在构建MAC头部信息时需要填入接收方的MAC地址(不一定是最终接收者的MAC地址,一般来说也不是最终目的地的MAC地址,因为一般网络中的数据都要经过路由转发才能到达接收方)信息,但是此时还没出现过接收方MAC地址的信息,这就需要我们通过某种手段获得接收方MAC地址,此时我们知道接收方的IP,所以协议栈设计了以接收方IP地址获取接收方MAC地址的功能,这就是ARP地址解析协议。

ARP简单来说就是通过广播的方法获得响应方返回的信息。一图明解

不过这里有一个问题,如果我们每次发包都要查询接收方的MAC地址,这效率有点让人难以接受,所以放心,协议栈设计者设计了一个叫做ARP缓存的东西,用于缓存最近获取到的ARP缓存信息,就是IP和MAC地址的对应信息。每次我们使用ARP时都先在ARP缓存中查找一下看是不是有我们想要的信息,没有的话再进行ARP查询。ARP查询会每隔几分钟删除一次,简单粗暴,但是很实用,能够防止IP地址变化导致的ARP缓存失效问题。

至此,IP模块工作完成,接下来就是网卡的工作了。

网卡的工作

IP模块生成的网络包其实就是内存中的一串数字信息,网卡就是负责将这些数字信息转化为光信号或电信号,从网线上发送出去。要想网卡工作起来需要网卡驱动程序,所有硬件设备工作起来都需要驱动程序的支持,键盘、鼠标、显卡、声卡等,一般设备厂商都会提供这些驱动程序,不需要我们自己编写。

网卡内部结构如下图所示

网卡通电后不是立即开始工作的,而是首先要先初始化,一般操作系统刚启动时会对硬件进行初始化操作,网卡的ROM中保存着该网卡全球唯一的MAC地址,这是网卡生产时厂家根据全球通用的规范写入的一个地址,初始化时将这个MAC地址读出后就可以对MAC模块进行设置,MAC模块就知道自己的MAC地址了。也可以自己设置MAC地址,这时网卡会忽略ROM中的的MAC地址。网卡初始化完成后就可以等待IP的委托了。

网卡是怎么工作的

下面介绍一下网卡是怎么把数字信号转化为光信号还是电信号的。

IP模块将数据包委托给网卡后,网卡驱动程序从内存中读取出数据包,复制到网卡的缓冲区内,然后向MAC模块传递发送网络包的命令,接下来就是MAC模块的工作了。

MAC模块先从缓冲区取出数据包,并在数据包头部添加报头和起始帧分界符,在末尾加上用于检测错误的帧校验序列。示意图如下

报头是一串010101……等0和1交替的比特序列,长度是56比特,它的作用是确定包的读取时机。当这些比特序列被转化成电信号后会形成下图所示的波形。

先讲一下通过电信号读取数据的原理。

用电信号表达数字信息时,我们约定用0和1两种比特分别对应特定的电压和电流,如下图中(a)所示

通过测量电信号中的电压和电流的变化,还原出0和1两种比特的值就是通过电信号来读取数值的过程。但是实际情况中不是所有的信号都像上图中a中的那样有分隔每隔比特的辅助线,要解决这个问题,我们采用的方法是在数据信号之外再发送一组时钟信号用来区分比特间隔。当时钟信号从下往上变化时读取电信号的值,然后用0或1对应就可以了。不过这个方法也存在问题,当传输距离较远、网线较长时,两条线路的长度会发生差异,数据信号和时钟信号的传输会产生时间差,时钟会发生偏移。

要解决时钟偏移的问题,我们采用的方法是将数据信号和时钟信号叠加在一起的方法,如想入c所示,发送饭将这种信号发送给接收方,由于时钟信号是按固定频率采样的,只要能够找到这个变化的周期,就可以直接从c中提取出时钟信号b,进而计算出数据a,这里重点是怎么判处时钟信号的变化周期,由于时钟信号是以固定频率变化的,只要我们观察一段时间就可以确定这个频率,这就是报头的作用。

报头后的起始帧分界符表示包起始位置,末尾的FCS帧校验序列用于检查包传输过程中因噪声导致的波形异常、数据错误,它是一段32比特的序列,是通过一个公式对包从头到尾的所有内容进行计算而得出来的。

加上报头、起始帧分界符和FCS之后,我们就可以将包通过网线发送出去了,发送信号的操作有两种,一种是实用集线器的半双工模式,另一种是实用交换机的全双工模式。接下来PHY(MAU)模块会将信号转换成可以在网线上传输的格式,并通过网线发送出去。

接收网络包

接收到的数据也是通过网线传入到网卡设备的,信号的开头是报头,通过报头的波形同步时钟,然后找到起始帧分界符,将分界符后面的信号转化为数字信息。这个过程和发送时是相反的,PHY(MAU)模块先开始工作,然后是MAC模块。PHY(MAU)模块将信号转换成通用格式并发给MAC模块。MAC模块从头将信号转化成数字信息,并存放到缓冲区,到达信号结尾时检查FCS,对比计算的FCS,如果二者不一致,则这个包会被当作错误报而丢弃。如果FCS一致,接下来就要看一下MAC头部总接收方的MAC地址与网卡在初始化时分配的MAC地址是否一致,以判断这个包是不是发给自己的。如果不是发给自己的包就丢弃,如果时发给自己的就放入缓冲区。到这里,网卡的工作就结束了,接下来网卡会通知计算机接收到了一个网络包。

通知计算机的操作使用了一个叫做中断的机制。中断的过程是这样的,网卡想扩展总线中的中断信号线发送信号,该信号通过计算机的中断控制器连接到CPU,当产生中断信号时,CPU会暂时挂起正在处理的任务,切换操作系统中的中断处理程序,然后中断处理程序会调用网卡驱动,控制网卡执行接收操作。

网卡驱动被中断处理程序调用后,会从网卡的缓冲区中取出收到的包,并通过MAC头部中的以太类型字段判断协议的类型。现在大部分是TCP/IP协议,但是也还有其他类型的协议比如IPX/SPX,以及Mac电脑中使用的AppleTalk等协议。

如果以太类型时0800,网卡驱动会将其交给TCP/IP协议栈进行处理,接下来就是IP模块的工作,第一步是检查IP头部,确认格式是否正确,如果格式没有问题下一步就是查看接收方的IP地址,判断本机IP地址与网卡的地址是否一致,确认无误后就可以接收这个包了。

这里需要注意一下IP协议有一个分片的功能,具体我们后边再说。IP模块接收到包后会将他们还原成原始的包,分片的包会在IP头部的标志字段中进行标记,当收到分片的包时,IP模块会将其暂时存在内部的内存空间,然后等待IP头部中具有相同ID的包全部到达,根据头部中分片偏移量字段,将所有的包重组,还原成原始的包。

然后IP模块会将包交给TCP模块,TCP模块根据IP头部中接收方和发送方的IP地址,以及TCP头部中接收方和发送方的端口来查找响应的套接字,找到相应的套接字后接可以根据套接字中记录的通信状态,执行响应的操作。比如包的内容是应用程序数据,则返回确认接收的包,并将数据放入缓冲区,等待应用程序读取;如果是建立或断开链接的控制包,则返回响应的控制包,并告知应用程序建立或者断开连接的操作状态。

到这里IP数据包相关的基础知识就讲完了,下一次我们讲一下网络数据传输过程中相应的硬件设备的作用。