《网络是怎样连接的》学习总结-第二章下

目录

[2. 第二章 用电信号传输TCP/IP数据------探索协议栈和网卡](#2. 第二章 用电信号传输TCP/IP数据——探索协议栈和网卡)

[2.5 IP与以太网的收发操作](#2.5 IP与以太网的收发操作)

[2.5.1 包的基本知识](#2.5.1 包的基本知识)

[2.5.2 包收发操作概览](#2.5.2 包收发操作概览)

[2.5.3 生成包含接收方IP地址的IP头部](#2.5.3 生成包含接收方IP地址的IP头部)

[2.5.4 生成以太网用的MAC头部](#2.5.4 生成以太网用的MAC头部)

[2.5.5 通过ARP查询目标路由器的MAC地址](#2.5.5 通过ARP查询目标路由器的MAC地址)

[2.5.6 以太网的基本知识](#2.5.6 以太网的基本知识)

[2.5.7 将IP包转换成电或光信号发送出去](#2.5.7 将IP包转换成电或光信号发送出去)

[2.5.8 给网络包再加3个控制数据](#2.5.8 给网络包再加3个控制数据)

[2.5.9 向集线器发送网络包](#2.5.9 向集线器发送网络包)

[2.5.10 接收返回包](#2.5.10 接收返回包)

[2.5.11 将服务器的响应包从IP传递给TCP](#2.5.11 将服务器的响应包从IP传递给TCP)

[2.6 UDP协议的收发操作](#2.6 UDP协议的收发操作)

[2.6.1 不需要重发的数据用UDP发送更高效](#2.6.1 不需要重发的数据用UDP发送更高效)

[2.6.2 控制用的短数据](#2.6.2 控制用的短数据)

[2.6.3 音频和视频数据](#2.6.3 音频和视频数据)


2. 第二章 用电信号传输TCP/IP数据------探索协议栈和网卡

2.5 IP与以太网的收发操作

2.5.1 包的基本知识

包是由头部和数据部分组成的,如图1。

图1

这一节大概介绍了后面的整个包的传送流程,我自己做的总结如下:

包被IP模块发送出去后,会被网卡转换为光或者电信号,然后从网卡连接的网线发送出去,经过各个网络转发设备,转发到哪个设备是通过数据包的MAC头部来得知的,每经过一个转发设备(路由器和集线器两种,路由器的工作是根据目标地址判断下一个路由器的位置,集线器的工作是在子网中将网络包传输到下一个路由)就会去更新MAC地址,从而转发到下一个转发设备,反复这样,然后发送到对应的设备的网卡,转发到之后,经过查看MAC地址查看是否发送正确,如果正确再查看IP地址是否为发送到本机的包,是的话就保留,然后IP协议将各个包重组起来,然后再查看TCP头部的端口号,得到端口号后就发送到对应的应用程序,所有包发送完成后,就四次挥手断开连接。

上面红字也可以这样理解,一个数据包中包含IP头部和MAC头部**,IP头部就是给IP协议用的,对应的物理设备就是路由器,在传输过程中不断更新IP头部里的IP** 。MAC头部就是给以太网协议用的,对应的物理设备就是集线器 ,IP协议得知下一个路由器的IP地址后,就委托以太网协议转发出去,但是路由器本身这个设备的唯一标识是MAC地址(以太网地址,每个路由器出厂设置都不同),所以IP协议会找到下一个路由器的MAC地址并写入MAC头部,然后MAC协议就知道要发到哪个路由器上了,就把包发出去。但是后面又有过介绍说现在的路由器已经具备自己转发包的功能了,所以不需要集线器了,后面的章节会提到。

2.5.2 包收发操作概览

上面是整体流程,这一小节介绍了IP模块的包收发流程。这一节可以记住,后面都是围绕这个流程来讲其中的细节。

包收发操作的起点是TCP模块委托IP模块发送包,这个委托过程就是TCP协议在数据包前面加上TCP头部,然后将头部和数据包当作一个整体传递给IP模块,这个TCP头部加数据内容的部分统称为网络包。

然后收到委托后,IP模块会在前面加上IP头部和MAC头部。IP头部包含IP协议规定的根据IP地址将包发往目的地所需的控制信息;MAC头部包含通过以太网的局域网将包传输至最近的路由器所需的控制信息。

然后,封装好的网络包会被传递给网络硬件,网络硬件可能是计算机上的板卡、也可能是笔记本电脑的PCMCIA卡,也可能是电脑上的芯片,这本书统称为网卡。传递给网卡的数据是一串0和1组成的数字信息,网卡会将这部分数据转换为电信号或者光信号(第三章的内容),并通过网线或光纤发送出去,然后到达集线器、路由器等转发设备最终发送给接收方。达到接收方后网卡会将光电信号转化为0和1数字信息,然后交给IP模块,然后IP模块会将TCP头部和TCP数据包发送给TCP模块,然后接下来就是TCP模块的操作了。

有一点要注意:IP模块是将TCP头部和数据看作一整块二进制数据,不关心这两者是都有还是只有其中一部分,因为像三次握手四次挥手这种知识发的控制包,没有数据包。所以IP模块的职责知识将TCP委托的东西打包发送出去,或者是接收发送来的包,不关心其中的内容是否正确或者有没有失序等等。

图2

2.5.3 生成包含接收方IP地址的IP头部

从这一节开始就是介绍IP模块具体的工作流程了。

IP模块收到TCP的委托后首先会生成IP头部并附加在TCP头部的前面。其中最重要的是接收方IP地址,这个地址由TCP模块告知IP模块,是由TCP在执行连接操作时从应用程序那里获取的这个地址(DNS解析、三次握手)。

图3

接下来还需要填写发送的IP地址。但是实际上一台计算机可能有多个IP地址,因为一般的计算机只有一个网卡,而一个网卡对应一个IP地址,所以一般情况下认为一台计算机只有一个IP。但是一台计算机有多个网卡时,这时一台计算机就有多个IP地址了。那么应该如何判断使用哪个网卡的IP呢?

其实计算机中有个叫IP表的,也叫路由表。在第三章会详解介绍。在电脑上可以通过 route print来显示路由表。首先,对套接字中记录的目的地IP地址与路由表左侧的network destinnation栏比较,找到与IP地址左侧相匹配的一行,然后interface列就表示网卡的网络接口,就是网卡的IP。Gateway列就表示下一个路由器的IP地址,将包发送到这个IP地址。第一行中,目标地址和子网掩码都为0.0.0.0,这表示默认网关,如果其他所有条目都无法匹配,就会自动匹配这一行。

这样我们就知道了该使用哪块网卡发送了。然后还需要填写协议号,表示包的内容来自哪个模块。例如如果是TCP委托的则设置为06(十六进制),如果是UDP模块委托的就设置为17(十六进制),这些值都是按照规则来设置的。

图4

2.5.4 生成以太网用的MAC头部

生成完IP头部之后,还需要在IP头部前附加MAC头部。在TCP、IP中我们只需要知道IP地址就知道包要发往哪里,但在以太网的世界中是不行的,它必须通过MAC地址才能转发过去。我个人的理解就是IP地址和MAC地址是两个不同的概念,IP地址你看作是一个人的姓名和电话号码,就是我知道这个包是发给你的并且我可以通过电话联系你,但是我不知道你家具体住址在哪里,所以我还要知道你的住址(MAC地址),所以我需要打电话问你你家住址是什么,我好把这个数据包送到你家。

图5

如上表有三个字端。以太网类型类型如图,它表示在MAC头部后的的数据内容的类型。发送方的MAC地址在这里填写网卡本身的MAC地址,MAC地址是在网卡生产时就写入ROM里的,只要将这个值读取出来写入MAC头部就可以,在上一小节的路由表里我们已经知道使用哪个网卡发送包了,取出它的MAC地址就可以(实际上操作系统的网卡驱动程序在初始化网卡时会将网卡的MAC地址存入内容,所以之后从内存取网卡的MAC地址就可以)。

最难搞的是接收方的MAC地址,因为这个时候还没和对方通信过,我们还不知道下一个转发设备的MAC地址,我们唯一知道的就是通过路由表中的GateWay列,知道了转发设备的IP地址,所以我们还需要执行根据IP地址查询MAC地址的操作(就如我上面说的根据电话号码询问你家住址是什么)。

2.5.5 通过ARP查询目标路由器的MAC地址

ARP:地址解析协议。

ARP就是利用广播,可以把包发送给连接在同一以太网中的所有设备。ARP就是利用广播进行提问:"xxx这个IP是谁的?请把你的MAC地址告诉我",然后就会有人回答并返回它的MAC地址。

同样,ARP也有缓存,不然每次都发一次ARP会增加网络负荷。在发送包时先查询一下ARP缓存,如果缓存中已经保存了对方的MAC地址,就不需要发送ARP擦护心,直接使用ARP缓存中的地址。在终端中显示所有ARP缓存的命令是"arp -a"。

至此,IP模块的打包过程就完成了。

2.5.6 以太网的基本知识

如图6a所示,最先开始的以太网原型就是相当于一根网线,当一台计算机发送信号时,信号会通过网线流过整个网络,最终到达所有设备,然后接收方通过包里的MAC地址判断是否是发给自己的,是就接收,不是就丢弃。

然后a后来变成了b的结构。这个结构式将主干网线替换成了一个中继式集线器,将收发器网线替换成了双绞线。不过虽然网络结构有变化,但信号依然会发送给所有设备。

后来,图3这样的交换式集线器结构普及开来,现在说的以太网就是这样的结构,这个结构的信号只会传递到根据MAC地址指定的设备,不会传给其他设备了。

那么以太网到底是什么,书中原话:"尽管以太网经历了数次变迁,但其基本的 3 个性质至今仍未改变,即将包发送到 MAC 头部的接收方 MAC 地址代表的目的地,用发送方MAC 地址识别发送方,用以太类型识别包的内容。因此,大家可以认为具备这 3 个性质的网络就是以太网 。 "

图6

2.5.7 将IP包转换成电或光信号发送出去

IP生成的网络包只是存放在内存中的一串数字信息,需要将数字信息转换成光或电信号才能在网线上传输。负责执行这一操作的是网卡,但网卡也无法单独工作,需要由网卡驱动程序操作。网卡驱动程序是厂商开发的专用程序。

网卡的主要构成元素如图所示。

网卡并不是通上电之后马上就开始工作的,而是和其他硬件一样都需要进行初始化。打开计算机启动操作系统时,网卡驱动程序就会对硬件进行初始化,然后硬件才进入可以使用的状态。这些操作包括硬件错误检查、初始设置等步骤。网卡的ROM中保存着全世界唯一的MAC地址,是在生产网卡时就写入的。真正在MAC模块中生效的MAC地址就是网卡驱动程序进行初始化时在MAC模块中设置的那个MAC地址。在操作系统启动并完成这些初始化操作后,网卡就可以等待来自IP的委托了。

图7

2.5.8 给网络包再加3个控制数据

接下来看看网卡是如何将包转换成电信号并发送到网线中的。网卡驱动从IP模块获取包之后,会将其复制到网卡内的缓冲区中,然后向MAC模块发送发送包的命令。然后就该MAC模块工作了。

首先,MAC模块会将从缓冲区中取出,并在开头加上报头和起始帧分界符,在末尾加上用于检测错误的帧校验序列。

图8

报头是一串香10101010这样的1和0交替出现的比特序列,长度为56比特,它的作用是确定包的读取时机。当这些比特序列被转换成电信号后,就会形成如下图的波形,接收方在收到信号时遇到这样的波形就可以判断读取数据的时机。先讲讲如何通过电信号来读取数据。

图7

用电信号表达数字信息时,需要让0和1两种比特对应特定的电压和电流。如下图a中这样的电信号。而通过电信号读取数据就是通过测量信号中电压和电流的变化还原出0和1两种比特的值。然而实际中可不像下图中有辅助线帮助分割,因此在测量电压和电流时必须先判断出每个比特的界限在哪里。但是像a中右侧部分出现连续1或者连续0的信号,由于电压和电流没有变化,就没办法判断其中每个比特应该如何区分。

解决这个问题最简单的方法就是在数据信号之外再发送一组用来区分比特间隔的时钟信号。如下图b所示这样。当时钟信号从下往上变化时就去读取电压和电流的值,然后判断是0或者1就可以。但是当距离较远网线较长时,两条线路的长度会发生差异,数据信号和时钟信号的传输会产生时间差,时钟会发生偏移。

要解决这个问题,可以采用将数据信号和时钟信号叠加在一起的方法,如c所示。这个有点绕,具体过程是通过时钟信号的变化周期从C中提取出时钟信号,然后结合时钟信号和C就可以得出数据信号,那么此时我们就得到数据信号和时钟信号了,再通过上一段的方法,将数据信号中的带怒啊和电流值还原成0或1的比特。那么如何去找到这个时钟信号的变化周期呢?

时钟信号是以10Mbit/s或者100Mbit/s这种固定频率变化的,所以只要对信号进行一段时间观察就可以找到其变化周期。因此我们不能一开始就发送包的数据,而是要在前面加上一段用来测量时钟信号的特殊信号,这就是报头的作用。

图8

报头后面还有一个起始帧分界符,它的末尾排练有少许变化,接收方就以这一变化作为标记,从这里开始提取网络包数据。也就是说,起始帧分界符是一个用来表示包起始位置的标记。

末尾的FCS是用来检查包传输过程中因噪声导致的波形紊乱、数据错误等,它是一串32比特的序列,是通过一个公式对包中从头到尾所有内容进行计算得出来的,在接收方接收到包后,计算出的FCS如果和发送方计算出的FCS不同,就可以判断出数据有没有错误,有错误的话可能就会丢弃。

2.5.9 向集线器发送网络包

加上三个控制信息后接下来就可以将包从网线发送出去了。发送信号的操作分为两种,一种是使用集线器的半双工模式,另一种是使用交换机的全双工模式,本节介绍的是集线器,交换机在第三章介绍。
在半双工模式中,为了避免信号碰撞,首先要判断网线中是否存在其他设备发送的信号。如果有,则需要等待该信号传输完毕,因为如果在有信号时再发送一组信号,两组信号就会发生碰撞。当之前的信号传输完毕,或者本来就没有信号在传输的情况下,我们就可以开始发送信号了。首先, MAC 模块从报头开始将数字信息按每个比特转换成电信号,然后由 PHY(物理层装置),或者叫 MAU(介质连接单元) 的信号收发模块发送出去 90。在这里,将数字信息转换为电信号的速率就是网络的传输速率,例如每秒将 10 Mbit 的数字信息转换为电信号发送出去,则速率就是 10Mbit/s。
接下来,PHY(MAU)模块会将信号转换为可在网线上传输的格式,并通过网线发送出去。以太网规格中对不同的网线类型和速率以及其对应的信号格式进行了规定,但 MAC 模块并不关心这些区别,而是将可转换为任意格式的通用信号发送给 PHY(MAU)模块,然后PHY(MAU)模块再将其转换为可在网线上传输的格式。大家可以认为PHY(MAU)模块的功能就是对 MAC 模块产生的信号进行格式转换。
PHY(MAU)的职责并不是仅仅将MAC模块传递过来的信号通过网线发送出去,还需要监控接收线路中有没有信号进来。在开始发送信号前需要先确认有没有其他信号进来,没有才能发送,如果在发送到结束发送一只没有其他信号进来发送操作就算完成了。
但是也有可能出现多台设备同时进行发送操作的情况,如果有其他设备同时发送信号,这些信号就会通过接收线路传进来。在使用集线器的半双工模式中,一旦发生这种情况两组信号就会叠加,无法彼此区分出来,这就是所谓的信号碰撞。这种情况下,继续发送信号是没有意义的,因此发送操作会终止。为了通知其他设备当前线路已发生碰撞,还会发送一段时间的阻塞信号 94,然后所有
的发送操作会全部停止。
等待一段时间之后,网络中的设备会尝试重新发送信号。但如果所有设备的等待时间都相同,那肯定还会发生碰撞,因此必须让等待的时间相互错开。具体来说,等待时间是根据 MAC 地址生成一个随机数计算出来的。
当网络拥塞时,发生碰撞的可能性就会提高,重试发送的时候可能又会和另外一台设备的发送操作冲突,这时会将等待时间延长一倍,然后再次重试。以此类推,每次发生碰撞就将等待时间延长一倍,最多重试 10 次,如果还是不行就报告通信错误。

2.5.10 接收返回包

接收返回包和上面的过程就相反。信号的开头是报头,通过报头的波形同步时钟,然后遇到起始帧分界符时开始将后面的信号转换成数字信息。即PHY(MAU)模块先工作,然后再是MAC模块。首先,PHY(MAU)将信号转换成通用格式并发送给MAC模块,MAC模块再从头开始将信号转换为数字信息,并存放到缓冲区中。当到达信号末尾时还要检查FCS,如果计算出来的FCS和包末尾的FCS不一样,就把这个包当作错误包丢弃。

如果FCS没问题,那么就看MC头部中的接收方MAC地址与网卡初始化时分配给自己的MAC地址是否一致,如果一致就将包放入缓冲区中,到这里MAC模块的工作就完成了,接下来网卡就会通知计算机收到了一个包。

通知计算机的操作会使用一个叫中断的机制。在网卡执行接收包的过程中,计算机不是一致监控着网卡的活动的,而是取执行其他任务,所以计算机不会知道什么时候会收到一个包,必须让网卡去通知计算机,这个机制就是中断。

中断的工作流程如下。首先,网卡向扩展总线中的中断信号发送信号,该信号线通过计算机中的中断控制器连接到CPU。当产生中断信号时,CPU会暂时挂起正在处理的任务,切换到操作系统中的中断处理程序,然后,中断处理程序会调用网卡驱动,控制网卡执行相应的接收操作。
网卡驱动被中断程序调用后,会从网卡的缓冲区中取出收到的包,并通过MAC头部中的以太类型字端判断协议的类型。现在大多数情况都适用TCP/IP协议,但除了TCP/IP之外还有很多其他类型的协议,例如NetWare中使用的IPX/SPX,以及MAC电脑中使用的AppleTalk等协议。这些协议都被分配了不同的以太类型,如0080代表IP协议,网卡驱动就会把这样的包交给TCP/IP协议栈;如果时809B则表示AppleTalk协议,就把包交给AppleTalk协议栈,以此类推。

2.5.11 将服务器的响应包从IP传递给TCP

假设现在WEB服务器返回了一个网络包。网卡驱动会将其交给TCP/IP协议栈来进行处理。IP模块第一步是检查IP头部,确认格式是否正确,如果格式没有问题就查看接收方Ip地址,如果和客户端网卡的地址一致,就可以接收这个包。如果不是自己的Ip地址,客户端计算机不对包进行转发,Ip模块会通过ICMP消息将错误告知发送方,会发送下表中Destination unreachable消息告诉对方。

图9

如果接收方Ip地址正确,则这个包会被接收,这时还需要将被分片的包进行重组。分片的包会在IP头部的标志字端中进行标记,当收到分片的包时,IP模块会将其暂存在内部的内存空间中,然后等待IP头部中具有相同ID的包全部到达,这是因为同一个包的所有分片都具有相同的ID,此外,IP头部中还有一个分片偏移量字段。它表示当前分片在整个包中所处的位置,根据这些信息,在所有分片全部收到之后,就可以将它们还原成原始的包,这个操作就叫分片重组。
到这里,IP 模块的工作就结束了,接下来包会被交给 TCP 模块。TCP模块会根据 IP 头部中的接收方和发送方 IP 地址,以及 TCP 头部中的接收方和发送方端口号来查找对应的套接字。找到对应的套接字之后,就可以根据套接字中记录的通信状态,执行相应的操作了。例如,如果包的内容是应用程序数据,则返回确认接收的包,并将数据放入缓冲区,等待应用程序来读取;如果是建立或断开连接的控制包,则返回相应的响应控制包,并告知应用程序建立和断开连接的操作状态。

2.6 UDP协议的收发操作

2.6.1 不需要重发的数据用UDP发送更高效

简单来说就是那句经典的TCP可靠,UDP不可靠。TCP之所以很复杂是因为它要保证数据的完整性和可靠性,所以每次发送一个包都需要对方回复确认收到。但是有些情况下,即使没有TCP这样复杂的机制,也能够高效地重发数据,这种情况就是数据很短,用一个包就能装得下。如果只有一个包就不用考虑哪个包未送达了,如果丢了重发也只是重发一个包而已。此外,我们发送了数据,对方一般都会给出回复,只需要将回复的数据当作接收确认就可以,也不需要专门的接收确认包了。而且不用TCP,也就不需要发送那些用来建立和断开连接的控制包了。

2.6.2 控制用的短数据

像上面说的那种一个包的情况就适合用UDP。像DNS查询等交换控制信息的操作基本上都可以在一个包的大小范围内解决,这种场景中就可以用UDP来代替TCP。UDP 没有 TCP 的接收确认、窗口等机制,因此在收发数据之前也不需要交换控制信息,也就是说不需要建立和断开连接的步骤, 只要在从应用程序获取的数据前面加上 UDP 头部,然后交给 IP 进行发送就可以了(表 2.5)。接收也很简单,只要根据 IP 头部中的接收方和发送方 IP 地址,以及 UDP 头部中的接收方和发送方端口号,找到相应的套接字并将数据交给相应的应用程序就可以了。除此之外,UDP 协议没有其他功能了,遇到错误或者丢包也一概不管。因为UDP 只负责单纯地发送包而已,并不像 TCP 一样会对包的送达状态进行监控,所以协议栈也不知道有没有发生错误。但这样并不会引发什么问题,因此出错时就收不到来自对方的回复,应用程序会注意到这个问题,并重新发送一遍数据。这样的操作本身并不复杂,也并不会增加应用程序的负担。

图10

2.6.3 音频和视频数据

发送音频和视频数据时也会使用UDP。音频和视频数据必须在规定的时间内送达,一旦送达晚了,就会错过播放时机,导致声音和图像卡顿。如果像TCP一样通过接收确认响应来检查错误并重发,重发的过程需要消耗一定的时间,因此重发的数据很可能已经错过了播放的时机。一旦错过播放时机,重发数据也是没有用的,因为声音和图像已经卡顿了,是无法挽回的。当然可以用高速线路让重发的数据在规定时间内送达,但这样一来就要增加几倍的带宽才行。此外,音频和视频中缺少了某些包并不会产生严重的问题,只是会产生一些失真和卡顿而已,一般都是可接受的。

在这些无需重发数据,或者是重发了也没什么意义的情况下,使用UDP发送数据的效率会更高。

相关推荐
cwtlw9 分钟前
CSS学习记录20
前端·css·笔记·学习
谢道韫66621 分钟前
今日总结 2024-12-24
javascript·vue.js·elementui
茶颜悦色vv22 分钟前
Wireshark(1)
网络·web安全·网络安全·wireshark
一朵好运莲22 分钟前
React引入Echart水球图
开发语言·javascript·ecmascript
ascarl201023 分钟前
【Nginx系列】---Nginx配置tcp转发
运维·tcp/ip·nginx
紫罗兰盛开31 分钟前
分布式调度框架学习笔记
笔记·学习
我叫czc37 分钟前
【Python高级353】python实现多线程版本的TCP服务器
服务器·python·tcp/ip
xianwu54343 分钟前
反向代理模块。开发
linux·开发语言·网络·c++·git
Kobebryant-Manba43 分钟前
kafka基本概念
分布式·学习·kafka
brhhh_sehe1 小时前
重生之我在异世界学编程之C语言:深入文件操作篇(下)
android·c语言·网络