写在前面的话:在这里我们要学习整理的是协议栈和网卡探索的读书笔记,其中的TCP/IP,三次握手,SYN,ACK,ARP,ICMP等等,希望在学习之后,大家都能对这些有一定的概念,知道是怎么回事!有道笔记之前写的居然没有保存下来,坑啊!!!!
在上一篇中我们介绍了协议栈的调用流程是:
1.创建套接字(创建套接字阶段)
2.将管道连接到服务器端的套接字上(连接阶段)
3.收发数据(通信阶段)
4.断开管道并删除套接字(断开阶段)
这里我们就用这个流程来整理,首先看一下协议栈的内部结构:
分为几个部分,分别承担不同的功能。 这张图中的上下关系是有一定规则的,上面的部分会向下面的部分委派工作,
下面的部分接受委派的工作并实际执行,这一点大家在看图时可以参 考一下。这里不在展开...
创建套接字
实际上套接字的实体就是通信控制信息。
在协议栈内部有一块用于存放控制信息的内存空间,这里记录了用于 控制通信操作的控制信息,例如通信对象的 IP
地址、端口号、通信操作的 进行状态等。本来套接字就只是一个概念而已,并不存在实体,如果一定
要赋予它一个实体,我们可以说这些控制信息就是套接字的实体,或者说
存放控制信息的内存空间就是套接字的实体。
协议栈是根据套接字中记录的控制信息来工作的。
我们可以通过netstat -ano
开查看windows
下的套接字信息,这里就不在展开了...
创建套接字
创建套接字实际上就是调用下面代码:
<描述符> = socket(<使用iPv4>,<使用TCP>);
创建套接字干的第一件事就是分配内存空间,然后向其写入初始状态。
描述符其实是用来区分协议栈中多个套接字用的号码牌。
连接服务器
在这里连接服务器也需要一些准备工作:
客户端:
把服务器的IP地址和端口号等信息告知协议栈。
服务器:
创建套接字,等待连接。
连接实际上是通信双方交换控制信息,在套接字中记录这些必要信息并准备数据收发的一连串操作。
而所谓控制信息就是用来控制数据收发所需的一些信息,IP地址和端口号就是典型的例子。
同时我们需要准备一块内存空间作为数据的缓存区,在数据收发操作时使用。
负责保存控制信息的头部
第一类:是客户端和服务器相互联络时交换的控制信息。这些信息不仅
连接时需要,包括数据收发和断开连接操作在内,整个通信过程中都需要, 这些内容在 TCP
协议的规格中进行了定义。具体来说,表 2.1 中的这些字 段就是 TCP 规格中定义的控制信息
A。这些字段是固定的,在连接、收发、 断开等各个阶段中,每次客户端和服务器之间进行通信时,都需要提供这
些控制信息。
[图片上传失败...(image-17ffc5-1527905991442)]
这些字段是固定的,在连接,收发,断开等各个阶段中,每次客户端和服务器之间进行通信时,都需要提供这些控制信息。例如:
[图片上传失败...(image-b653e5-1527905991442)]
如上图a
所示,这些信息会添加到客户端与服务器之间传递的网络包的开头。在连接阶段,由于数据收发还没有开始,网络包中没有实际的数据,只有控制信息。这些控制信息位于网络包的开头。因此被称为头部。此外,以太网和 IP
协议也有 自己的控制信息,这些信息也叫头部,为了避免各种不同的头部发生混淆, 我们一般会记作 TCP
头部、以太网头部 B、IP 头部。
第二类:那就是保存在套接字中,用来控制协议栈操 作的信息
A。应用程序传递来的信息以及从通信对象接收到的信息都会保存在这里,还有收发数据操作的执行状态等信息也会保存
在这里,协议栈会 根据这些信息来执行每一步的操作。
连接操作的实际过程
实际上具体的连接操作时从调用Socket
库中的connect
库开始的;
connect(< 描述符 >, < 服务器 IP 地址和端口号 >, ...)
这里整体的描述都是书上的,描述的非常清晰:
上面的调用提供了服务器的 IP 地址和端口号,这些信息会传递给协议 栈中的 TCP 模块。然后,TCP 模块会与该 IP
地址对应的对象,也就是与 服务器的 TCP 模块交换控制信息,这一交互过程包括下面几个步骤。首
先,客户端先创建一个包含表示开始数据收发操作的控制信息的头部。如 表 2.1
所示,头部包含很多字段,这里要关注的重点是发送方和接收方的
端口号。到这里,客户端(发送方)的套接字就准确找到了服务器(接收
方)的套接字,也就是搞清楚了我应该连接哪个套接字。然后,我们将头 部中的控制位的 SYN 比特设置为
1,大家可以认为它表示连接 A。此外还需 要设置适当的序号和窗口大小,
当 TCP 头部创建好之后,接下来 TCP 模块会将信息传递给 IP 模块并 委托它进行发送 A。IP
模块执行网络包发送操作后,网络包就会通过网络到 达服务器,然后服务器上的 IP 模块会将接收到的数据传递给 TCP
模块, 服务器的 TCP 模块根据 TCP 头部中的信息找到端口号对应的套接字,也
就是说,从处于等待连接状态的套接字中找到与 TCP 头部中记录的端口号
相同的套接字就可以了。当找到对应的套接字之后,套接字中会写入相应 的信息,并将状态改为正在连接
B。上述操作完成后,服务器的 TCP 模块会 返回响应,这个过程和客户端一样,需要在 TCP 头部中设置发送方和接收
方端口号以及 SYN 比特 C。此外,在返回响应时还需要将 ACK 控制位设为
1D,这表示已经接收到相应的网络包。网络中经常会发生错误,网络包也会
发生丢失,因此双方在通信时必须相互确认网络包是否已经送达 E,而设置 ACK
比特就是用来进行这一确认的。接下来,服务器 TCP 模块会将 TCP 头部传递给 IP 模块,并委托 IP
模块向客户端返回响应。
然后,网络包就会返回到客户端,通过 IP 模块到达 TCP 模块,并通 过 TCP
头部的信息确认连接服务器的操作是否成功。如果 SYN 为 1 则表示连接成功,这时会向套接字中写入服务器的 IP
地址、端口号等信息,同 时还会将状态改为连接完毕。到这里,客户端的操作就已经完成,但其实还
剩下最后一个步骤。刚才服务器返回响应时将 ACK 比特设置为 1,相应地, 客户端也需要将 ACK 比特设置为 1
并发回服务器,告诉服务器刚才的响应 包已经收到。当这个服务器收到这个返回包之后,连接操作才算全部完成。
现在,套接字就已经进入随时可以收发数据的状态了,大家可以认为
这时有一根管子把两个套接字连接了起来。当然,实际上并不存在这么一
根管子,不过这样想比较容易理解,网络业界也习惯这样来描述。这根管 子,我们称之为连接
A。只要数据传输过程在持续,也就是在调用 close 断 开之前,连接是一直存在的。
建立连接之后,协议栈的连接操作就结束了,也就是说 connect 已经 执行完毕,控制流程被交回到应用程序。
收发数据
数据收发操作时从应用程序调用write
将要发送的数据交给协议栈开始的。协议栈收到数据后执行发送操作,有几个要点:
1,协议栈不关心应用程序传来的数据是什么内容,都是一堆二进制字节序列而已。应用程序调用write
时会制定发送数据的长度。
2.协议栈并不是已收到数据就马上发送出去,而是会将数据存放在内部的发送缓冲区中,
那么需要积累多少才会把数据发送出去呢,这里需要根据以下几个要素来判断:
第一个是:判断要素是每个网络包容纳的数据长度,协议栈会根据一个叫做MTU的参数来进行判断。
MTU:一个网络包的长度,以太网中一般为1500字节。头部中包括了IP头部和TCP头部。
MSS:除去头部之后,一个网络包能容纳的TCP数据的最大长度。头部是40,MSS就是1460字节。
第二个是:时间。
当应用程序发送数据的频率不高的时候,如 果每次都等到长度接近 MSS
时再发送,可能会因为等待时间太长而造成发这种情况下,即便缓冲区中的数据长度没有达到 MSS,也应该果
断发送出去。为此,协议栈的内部有一个计时器,当经过一定时间之后, 就会把网络包发送出去。
上面两个要素是互相矛盾的,所以协议栈也给了应用程序一个选择就是可以直接发送。
对较大数据进行拆分
当我们发送一个较大的数据时,发送缓存区中的数据会超过MSS的长度,这个时候我们就不用在继续等待了,而是把数据进行拆分以后直接发送。
数据拆分完毕以后,或者要准备发送数据时,我们给每一个数据前面加上TCP头部,并根据套接字中记录的控制信息标记发送方和接收方的端口号,然后交给IP模块来执行发送数据的操作。
使用ACK号确认网络包是否已收到
这里我们按着图来说明吧:
基本原理如下:
1.TCP拆分数据,把每一块的数据相当于从头开始的第几个字节算好,
2.在发送数据包,把算好的字节写在TCP头部中,也就是写在序号字段中。
3.发送数据的长度也告知对方。(其实这里是接收方通过网络包的长度减去头部的长度计算得出的),这样就可以知道发送的
数据是从第几个字节开始的,长度是多少?同时接受放还能坚持 收到的网络包有没有遗漏。
4.比如,收到的是1460字节,那么它下次收到的序号应该是1461,可是如果收到的是2921,那么就说明以后了。
5.这里先说没有遗漏,接收方会将目前为止接收到的数据长度加起来,计算出一共收到了多少个字节,然后将这个数值写入TCP头部的ACK号中,然后发送给发送方。
6.那么如果有遗漏呢? 它会计算已经收到的连续的包,计算最后它的长度是多少,一共收到了多少个字节,然后把它发送给发送方,而缺失的那部分因为我们并没有收到,所以我们并不会发送确认ACK给发送方,而发送方如果没有收到确认的ACK号,就说明这一个网络包的数据接收方并没有收到,它就会从缓冲区取出这个包,重新发送,直到收到确认ACK为止。
在实际通信中,序号不是从1开始的,而是一个随机数计算出来的初始值,在我们连接的过程中,将SYN设置为1,同时也设置了序号字段的值。这里就是代表需要的初始值。
什么是SYN?
我们在前面讲连接操作的时候说过 SYN 为 1 表示进行连接,这是因为将 SYN 设为 1
并告知初始序号这一操作仅在连接过程中出现,因此发送 SYN 为 1
的网络包就表示发起连接的意思。实际上,SYN 是 Synchronize
(同步)的缩写,意思是通过告知初始序号使通信双方保持步调一致,以便 完成后续的数据收发检查,这才是 SYN
原本的含义。
孀居的传输是双向的交互
实际的工作过程:
首先,客户端 在连接时需要计算出与从客户端到服务器方向通信相关的序号初始值,并
将这个值发送给服务器(图 2.9 1)。接下来,服务器会通过这个初始值计 算出 ACK 号并返回给客户端(图 2.9
2)。初始值有可能在通信过程中丢 失,因此当服务器收到初始值后需要返回 ACK 号作为确认。同时,服务
器也需要计算出与从服务器到客户端方向通信相关的序号初始值,并将这个值发送给客户端(图 2.9
2)。接下来像刚才一样,客户端也需要根据服 务器发来的初始值计算出 ACK 号并返回给服务器(图 2.9
3)。到这里,序 号和 ACK 号都已经准备完成了,接下来就可以进入数据收发阶段了。数
据收发操作本身是可以双向同时进行的,但 Web 中是先由客户端向服务器
发送请求,序号也会跟随数据一起发送(图 2.9 4)。然后,服务器收到数 据后再返回 ACK 号(图 2.9
5)。从服务器向客户端发送数据的过程则正好 相反(图 2.9 67)。
通过“序号”和“ACK 号”可以确认接收方是否收到了网络包。
根据网络包平均往返时间调整 ACK 号等待时间
TCP 采用了动态调整等待时间的方法,这个等待时间是 根据 ACK
号返回所需的时间来判断的。具体来说,TCP
会在发送数据 的过程中持续测量 ACK 号的返回时间,如果 ACK
号返回变慢,则相应
延长等待时间;相对地,如果 ACK 号马上就能返回,则相应缩短等待 时间 B。
使用窗口有效管理 ACK 号
首先你要明白什么是窗口,其实它说的窗口就是接收方的缓冲区大小,
在你发送的包和我处理的包的过程中,接收方首先会把包放到缓冲区,
然后按个取出按个进行处理,可是如果发送方发送了太多的网络包,而
接收方来不及处理,就会造成缓冲区溢出,所以我们在连接的时候,接
收方会把窗口的大小也发给发送方,告诉发送方,你悠着点发,别发的超了。
接收 HTTP 响应消息
简单总结:
首先,协议栈会检查收到的数据块和 TCP 头
部的内容,判断是否有数据丢失,如果没有问题则返回 ACK 号。然后,
协议栈将数据块暂存到接收缓冲区中,并将数据块按顺序连接起来还原出
原始的数据,最后将数据交给应用程序。具体来说,协议栈会将接收到的
数据复制到应用程序指定的内存地址中,然后将控制流程交回应用程序。
将数据交给应用程序之后,协议栈还需要找到合适的时机向发送方发送窗 口更新 B。
从服务器断开并删除套接字
完成数据发送的一方会发起断开过程,这里我们以服
务器一方发起断开过程为例来进行讲解。首先,服务器一方的应用程序会 调用 Socket 库的 close
程序。然后,服务器的协议栈会生成包含断开信息 的 TCP 头部,具体来说就是将控制位中的 FIN 比特设为
1。接下来,协议 栈会委托 IP 模块向客户端发送数据(图 2.12 1)。同时,服务器的套接字
中也会记录下断开操作的相关信息。
接下来轮到客户端了。当收到服务器发来的 FIN 为 1 的 TCP 头部时,
客户端的协议栈会将自己的套接字标记为进入断开操作状态。然后,为 了告知服务器已收到 FIN 为 1
的包,客户端会向服务器返回一个 ACK 号
(图 2.12 2)。这些操作完成后,协议栈就可以等待应用程序来取数据了。 过了一会儿,应用程序就会调用 read
来读取数据 A。这时,协议栈不会向应用程序传递数据 A,而是会告知应用程序(浏览器)来自服务器的数据
已经全部收到了。根据规则,服务器返回请求之后,Web 通信操作就全部
结束了,因此只要收到服务器返回的所有数据,客户端的操作也就随之结 束了。因此,客户端应用程序会调用 close
来结束数据收发操作,这时客 户端的协议栈也会和服务器一样,生成一个 FIN 比特为 1 的 TCP 包,然后 委托 IP
模块发送给服务器(图 2.12 3)。一段时间之后,服务器就会返回 ACK 号(图 2.12
4)。到这里,客户端和服务器的通信就全部结束了。
删除套接字
不过,套接字并不会立即被删除,而是 会等待一段时间之后再被删除。
(1)客户端发送 FIN
(2)服务器返回 ACK 号
(3)服务器发送 FIN
(4)客户端返回 ACK 号
总结
这个是TCP连接的整体流程:
数据收发操作的第一步是创建套接字。一般来说,服务器一方的应用
程序在启动时就会创建好套接字并进入等待连接的状态。客户端则一般是
在用户触发特定动作,需要访问服务器的时候创建套接字。在这个阶段, 还没有开始传输网络包。
创建套接字之后,客户端会向服务器发起连接操作。首先,客户端会 生成一个 SYN 为 1 的 TCP
包并发送给服务器(图 2.13 1)。这个 TCP 包
的头部还包含了客户端向服务器发送数据时使用的初始序号,以及服务器 向客户端发送数据时需要用到的窗口大小
A。当这个包到达服务器之后,服 务器会返回一个 SYN 为 1 的 TCP 包(图 2.13 2)。和图 2.13 1一样,这个
包的头部中也包含了序号和窗口大小,此外还包含表示确认已收到包1的 ACK 号
B。当这个包到达客户端时,客户端会向服务器返回一个包含表示确认的 ACK 号的 TCP 包(图 2.13
3)。到这里,连接操作就完成了,双方进 入数据收发阶段。
数据收发阶段的操作根据应用程序的不同而有一些差异,以 Web 为 例,首先客户端会向服务器发送请求消息。TCP
会将请求消息切分成一定大 小的块,并在每一块前面加上 TCP 头部,然后发送给服务器(图 2.13 4)。TCP
头部中包含序号,它表示当前发送的是第几个字节的数据。当服务器 收到数据时,会向客户端返回 ACK 号(图 2.13
5)。在最初的阶段,服务 器只是不断接收数据,随着数据收发的进行,数据不断传递给应用程序,
接收缓冲区就会被逐步释放。这时,服务器需要将新的窗口大小告知客户
端。当服务器收到客户端的请求消息后,会向客户端返回响应消息,这个 过程和刚才的过程正好相反(图 2.13 67)。
服务器的响应消息发送完毕之后,数据收发操作就结束了,这时就会 开始执行断开操作。以 Web
为例,服务器会先发起断开过程 A。在这个过程 中,服务器先发送一个 FIN 为 1 的 TCP 包(图 2.13
8),然后客户端返回一 个表示确认收到的 ACK 号(图 2.13 9)。接下来,双方还会交换一组方向相 反的 FIN 为 1 的
TCP 包(图 2.13 10)和包含 ACK 号的 TCP 包(图 2.13k)。 最后,在等待一段时间后,套接字会被删除。
IP 与以太网的包收发操作
包的基础知识
包是由头部和数据两部分构成的(图 2.14(a)。头部包含目的
地址等控制信息,大家可以把它理解为快递包裹的面单;头部后面就是委
托方要发送给对方的数据,也就相当于快递包裹里的货物。一个包发往目 的地的过程如图 2.15 所示。
在转发设备路由器中有一张记录了什么地址要往哪里发的表,根据头部的信息查询这张表,就可以判断出包的发送方向,这样一来,
每个包的就都鞥被发到各自要去的地方了。
(1)路由器根据目标地址判断下一个路由器的位置
(2)集线器在子网中将网络包传输到下一个路由
实际上,集线器是按照以太网规则传输包的设备,而路由器是按照 IP 规则传输包的设备,因此我们也可以作如下理解。
(1)IP 协议根据目标地址判断下一个 IP 转发设备的位置
(2)子网中的以太网协议将包传输到下一个转发设备
(a)MAC 头部(用于以太网协议)
(b)IP 头部(用于 IP 协议)
我们从上图可以看出,在实际传输中,目标地址的IP始终都没有改变,而MAC地址却一直改变,随着路由器根据目标网址找到下一个路由器的地址,修改MAC地址为下一个目标路由器的MAC地址。
IP模块会添加IP头部和MAC头部这两种头部。IP头部中包含了IP协议规定的,根据IP地址将包发往目的地所需的控制信
;MAC头部包含通过以太网的局域网将包传输至最近的路由器的所需的控制信息。
这里我们要认识到一点,IP的职责是将委托的东西打包送到对方手里,或者是将对方发送来的包接收下来。仅此而已,
无论要收发的包是控制包还是数据包,IP对各种类型的包的收发操作都是相同的。
大家要知道,大部分计算机上只有一块网卡,因此也只有一个IP地址,这种情况下我们可以认为这个Ip地址就是计算机的IP地址,但是服务器就没有那么简单了,服务器上有很多个网卡,情况就不是那么简单了,
IP地址实际上并不是分配给计算机的,而是分配给网卡的。所以当计算机上存在很多网卡时,每一块网卡都会自己的IP地址,在填写发送方的IP地址时应该使用哪一块网卡来发送这个包,也就相当于判断应该把包发送到哪个路由器,因此只要确定了目标路由器,也就确定了使用哪块网卡,也就确定了发送方的IP地址。
IP 头部的“接收方 IP 地址”填写通信对象的 IP 地址。 发送方IP地址需要判断发送所使用的网卡,并填写该网卡的 IP 地址。
那么,我们应该如何判断应该把包交给哪块网卡呢??
带着这个问题,我们看下面的描述:
路由器使用IP表判断下一个路由器位置的操作是一样的。因为协议栈的IP 模块与路由器中负责包收发的部分都是根据IP协议规则来进行包收发操作
的,所以它们也都用相同的方法来判断把包发送给谁。
这个IP表
就是路由表(Routing Table
,windows
下的查看命令是route print
),下面是书中的例子:
我们对照着这张图来说明:
首先:我们对套接字中记录的目的地IP地址与路由表左侧的Network Destination 栏进行比较,找到对应的一行。例如目标地址是
192.168.1.21
那么对应的就是192.168.1
也就是第6行,如果目标的IP地址是10.10.1.166
,那么对应的就是10.10.1
。所以,一次类推,我们需要找到IP地址与左边部分相匹配的那一项,
找到那一项后看右边数第2列和第3列的内容。右起第2列,也就是Interface
列,表示网卡等网络接口,这些网络接口可以将包发送给通信对象。此外,右起第3列,即GeteWay
列表示下一个路由器的IP地址,将包发给这个IP地址,该地址对应的路由器就会将包转发到目标地址。路由表的第1行中,目标地址和子网掩码都是0.0.0.0
,这表示默认网关,如果其他所有条目都没有匹配,就会自动匹配这一样。
A Gateway(网关)在 TCP/IP 的世界里就是路由器的意思。
B 如果Gateway 和 Interface 列的IP 地址相同,就表示不需要路由器进行转 发,可以直接将包发给接收方的 IP 地址。我们将在第 3 章详细介绍。
这样一来,我们就可以判断出应该使用哪块网卡来发送包了,然后就可以在IP头部的发送方IP地址中填上这块网卡对应的IP地址。
接下来还需要填写协议号。表示包的内容来自哪个模块。
TCP模块委托的内容:`06`(16进制)
UDP模块委托的内容:`17`(16进制)
现在我们使用的浏览器中,HTTP请求消息都是通过TCP
来传输的,因此这里会填写表示TCPd 06
生成以太网用的MAC头部
生成IP头部以后,接下来IP模块还需要在IP头部的前面添加MAC头部。我们介绍MAC头部的知识:
1.MAC头 部是以太网使用的头部,它包含了接收方和发送方的MAC地址等信息。
2.IP地址的长度是32比特,MAC地址的长度为48比特。
3.以太类型,就是使用的协议类型,下面是一些常见的类型。大家看图吧:
知道了MAC头部的知识以后,我们就知道了怎么生成MAC头部了:
1:设置以太类型,这里填写表示I协议的值0800
十六进制。
2:设置发送发的MAC地址,这里就填写网卡本身的MAC地址,
MAC 地址是在网卡生产时写入ROM 里的,只要将这个值读取出来写入MAC头部就可以了。
对于多块网卡的情 况,请大家回想一下设置发送方IP地址的方法 B。设置发送方IP地址时,
我们已经判断出了从哪块网卡发送这个包,那么现在只要将这块网卡对应
的MAC地址填进去就好了。
3:设置接收方的IP地址:
这个不复杂了,因为这个时间点上,我们还没有把包发送出去,所以就得搞清楚接收方应该把
包发送给谁,前面我们讲路由表的时候,就知道了只要查一下路由表,在路路由表中找到相匹
配的条目,然后把包发给`Gateway`列中IP地址就可以了。既然我们知道应该把包发送给谁,
那么只要将对方的MAC地址填上去 就好了,但到这里为止根本没有出现对方的MAC地址,
也就是说我们现
在根本不知道对方的MAC地址是什么。因此,我们还需要执行根据IP地
址查询MAC地址的操作。接下来就是查询目标路由器的MAC地址了。
IP 模块根据路由表 Gateway 栏的内容判断应该把包发送给谁
通过 ARP 查询目标路由器的 MAC 地址 (:Address Resolution Protocol,地址解析协议。
)
它的使用非常简单(书上这么说):
在以太网中,有一种叫作 广播的方法,可以把包发给连接在同一以太网中的所有设备。ARP就是利
用广播对所有设备提问:“×× 这个IP地址是谁的?请把你的MAC地址 告诉我。” 然后就会有人回答:“ 这个IP 地址是我的,我的MAC 地址是 ××××。”
如果对方和自己处于同一个子网中,那么通过上面的操作就可以得到 对方的MAC地址 B。然后,我们将这个MAC地址写入MAC头部,MAC 头部就完成了。
如果每次发送包都要这样查询一次,网络中就会增加很多ARP
包,因此我们会将查询结果放到一块叫作ARP缓存的内存空间中留着以后
用。也就是说,在发送包时,先查询一下ARP缓存,如果其中已经保存
了对方的MAC地址,就不需要发送ARP查询,直接使用ARP缓存中的
地址,而当ARP缓存中不存在对方MAC地址时,则发送ARP查询。
关于ARP缓冲这里不在详细描述,大家可以看书的110页。
以太网的基本知识
完成IP模块的工作之后,下面就该轮到网卡了,不过在此之前,我们 先来了解一些以太网的基本知识。
以太网是一种为多台计算机能够彼此自由和廉价地相互通信而设计的
通信技术,它的原型如图2.22(a)所示。从图上不难看出,这种网络的本
质其实就是一根网线。图上还有一种叫作收发器的小设备,它的功能只是
将不同网线之间的信号连接起来而已。因此,当一台计算机发送信号时,
信号就会通过网线流过整个网络,最终到达所有的设备。
这就好像所有人待在一个大房间里,任何一个人说话,所有人都能够听到,同样地,这种 网络中任何一台设备发送的信号所有设备都能接收到。不过,我们无法判
断一个信号到底是发给谁的,因此需要在信号的开头加上接收者的信息,
也就是地址。这样一来就能够判断信号的接收者了,与接收者地址匹配的
设备就接收这个包,其他的设备则丢弃这个包,这样我们的包就送到指定
的目的地了。为了控制这一操作,我们就需要使用表2.3中列出的MAC头
部。通过MAC头部中的接收方MAC地址,就能够知道包是发给谁的;而
通过发送方MAC地址,就能够知道包是谁发出的;此外,通过以太类型
就可以判断包里面装了什么类型的内容。以太网其实就这么简单 A。
这个原型后来变成了图2.22(b)中的结构。这个结构是将主干网线替 换成了一个中继式集线器 B,将收发器网线替换成了双绞线 C。不过,虽然网 络的结构有所变化,但信号会发送给所有设备这一基本性质并没有改变。
后来,图2.22(c)这样的使用交换式集线器 D 的结构普及开来,现在我
们说的以太网指的都是这样的结构。这个结构看上去和(b)很像,但其实里
面有一个重要的变化,即信号会发送给所有设备这一性质变了,现在信号只 会流到根据MAC 地址指定的设备,而不会到达其他设备了。当然,根据
MAC地址来传输包这一点并没有变,因此MAC头部的设计也得以保留。
尽管以太网经历了数次变迁,但其基本的3个性质至今仍未改变,即
将包发送到MAC头部的接收方MAC地址代表的目的地,用发送方MAC
地址识别发送方,用以太类型识别包的内容。因此,大家可以认为具备这
3个性质的网络就是以太网 E。
后续还有好几个主题的介绍:
将 IP 包转换成电或光信号发送出去
给网络包再加 3 个控制数据
向集线器发送网络包
接收返回包
将服务器的响应包从 IP 传递给 TCP
ICMP
UDP 协议的收发操作
后续主题之后会陆续添加,Over...