2.5 IP与以太网的包收发操作
包的基本知识
头部包含目的地址等控制信息,大家可以把它理解为快递包裹的面单;头部后面就是委托方要发送给对方的数据,也就相当于快递包裹里的货物。
首先,发送方的网络设备会负责创建包,创建包的过程就是生成含有正确控制信息的头部,然后再附加上要发送的数据。
接下来,包会被发往最近的网络转发设备。当到达最近的转发设备之后,转发设备会根据头部中的信息判断接下来应该发往哪里。这个过程需要用到一张表,这张表里面记录了每一个地址对应的发送方向,也就是按照头部里记录的目的地址在表里进行查询,并根据查到的信息判断接下来应该发往哪个方向。比如,如果查表的结果是“目标地址为××××的包应该发到××××号线路”,那么转发设备就会把这个包发到××××号线路去。
接下来,包在向目的地移动的过程中,又会到达下一个转发设备,然后又会按照同样的方式被发往下一个转发设备。就这样,经过多个转发设备的接力之后,包最终就会到达接收方的网络设备。
当然,发送方向接收方发送一个包,接收方可能也会向发送方返回一个包,此时的发送方到了接下来的某个时刻就会变成接收方。因此,我们不需要把发送方和接收方明确区分开来,在这里我们把发送方和接收方统称为终端节点(相应地,转发设备被称为转发节点或者中间节点。)。
(1)路由器根据目标地址判断下一个路由器的位置
(2)集线器在子网中将网络包传输到下一个路由
TCP/IP包包含如下两个头部:
(a)MAC头部(用于以太网协议)
(b)IP头部(用于IP协议)
这两个头部分别具有不同的作用。
首先,发送方将包的目的地,也就是要访问的服务器的IP地址写入IP头部中。这样一来,我们就知道这个包应该发往哪里,IP协议就可以根据这一地址查找包的传输方向,从而找到下一个路由器的位置,也就是图2.16中的路由器R1。
接下来,IP协议会委托以太网协议将包传输过去。这时,IP协议会查找下一个路由器的以太网地址(MAC地址),并将这个地址写入MAC头部中。这样一来,以太网协议就知道要将这个包发到哪一个路由器上了。
网络包在传输过程中(图2.16①)会经过集线器,集线器是根据以太网协议工作的设备。为了判断包接下来应该向什么地方传输,集线器里有一张表(用于以太网协议的表),可根据以太网头部中记录的目的地信息查出相应的传输方向。这张图中只有一个集线器,当存在多个集线器时,网络包会按顺序逐一通过这些集线器进行传输。
接下来,包会到达下一个路由器(图2.16②)。路由器中有一张IP协议的表,可根据这张表以及IP头部中记录的目的地信息查出接下来应该发往哪个路由器。为了将包发到下一个路由器,我们还需要查出下一个路由器的MAC地址,并记录到MAC头部中,大家可以理解为改写了MAC头部[插图]。这样,网络包就又被发往下一个节点了。
再往后的过程图上就没有画出来了。网络包会通过路由器到达下一个路由器R2。这个过程不断重复,最终网络包就会被送到目的地,当目的地设备成功接收之后,网络包的传输过程就结束了。
IP和以太网的分工,其中以太网的部分也可以替换成其他的东西,例如无线局域网、ADSL、FTTH等,它们都可以替代以太网的角色帮助IP协议来传输网络包。因此,将IP和负责传输的网络分开,可以更好地根据需要使用各种通信技术。
ADSL:电话线接入,使用ADSL技术,可将数据信号与语音信号加载一根电话线上。尽管ADSL技术有过一些技术发展,最后成熟的ADSL 2+理论上也能达到20M以上的接入速率,但是因为DSL技术对线缆的长度和性能要求较高,因此实际运营商一般只提供2-3M。后期在进行了大量的DSLAM下沉工程后可提供4-6M的速率。DSL技术可以说是运营商最大限度的利用了原先已经建设的铜缆资源,早期只需要在局端建设DSLAM就能提供业务,而随着速率和覆盖要求越来越高,进行了大量的DSLAM下沉建设,已解决2M及以上速率的覆盖。
以太网(FTTB+LAN):网线接入,使用以太网技术,只能承载数据,不能承载语音。大多小运营商采用FTTB+LAN的方式进行小区或商务楼的宽带接入,因为他们没有传统运营商的铜缆资源,因此重新覆盖的时候就采用光纤到小区的集中点,然后在小区内通过光纤结合网线的方式进行综合覆盖。而最终提供业务的通常是安装在楼道里的以太网交换机。目前来说通常楼道交换机采用百兆端口,因此理论上速率最高可以开到100M(二层,实际应用速率在85-90M)。但是因为汇聚收敛的关系,每个用户在高峰时期能否速率跑满还取决于小区出口的带宽。因此也就出现了所谓共享宽带的说法,实际上主要原因是他们的出口带宽普遍在高峰时会拥塞。传统运营商也会视情况建设LAN,比如一些区域ADSL无法提供高速率等。
光纤到户(FTTH):光纤接入,使用PON技术(EPON还是GPON取决于具体的运营商)。近几年传统运营商进行的大幅提速是基于光纤到户的改造。这个阶段的目的是通过光纤到户的改造,逐步将原先的铜缆替代掉。FTTH可支持高速率的接入,现在主流的是20-30M速率,一些高端用户也有50-100M的产品可选择。如果有需求,甚至更高速率也可以提供。FTTH结合IMS或SIP等核心网技术,可实现宽带电话承载在一根入户光纤上,由家庭网关实现综合业务的提供,高速宽带、高清IPTV、语音等都有家庭网关提供接入。光纤的改造可以说是从局端接入设备、光缆、楼道光分、入户光纤、家庭网关进行了全面的改造,因此投资巨大,但为了配合国家的发展方向实现宽带中国的战略,不惜成本的投入。
包收发操作概览
尽管我们说IP模块负责将包发给对方,但实际上将包从发送方传输到接收方的工作是由集线器、路由器等网络设备来完成的,因此IP模块仅仅是整个包传输过程的入口而已。
IP模块会将包的内容当作一整块数据,在前面加上包含控制信息的头部。刚才我们讲过,IP模块会添加IP头部和MAC头部这两种头部。IP头部中包含IP协议规定的、根据IP地址将包发往目的地所需的控制信息;MAC头部包含通过以太网的局域网将包传输至最近的路由器所需的控制信息。
IP模块负责添加如下两个头部。
(1) MAC头部:以太网用的头部,包含MAC地址
(2)IP头部:IP用的头部,包含IP地址
传递给网卡的网络包是由一连串0和1组成的数字信息,网卡会将这些数字信息转换为电信号或光信号,并通过网线(或光纤)发送出去,然后这些信号就会到达集线器、路由器等转发设备,再由转发设备一步一步地送达接收方。
包送达对方之后,对方会作出响应。返回的包也会通过转发设备发送回来,然后我们需要接收这个包。接收的过程和发送的过程是相反的,信息先以电信号的形式从网线传输进来,然后由网卡将其转换为数字信息并传递给IP模块(图2.17中的“③接收”)。接下来,IP模块会将MAC头部和IP头部后面的内容,也就是TCP头部加上数据块,传递给TCP模块。接下来的操作就是我们之前讲过的TCP模块负责的部分了。
IP模块会将TCP头部和数据块看作一整块二进制数据,在执行收发操作时并不关心其中的内容,也不关心这个包是包含TCP头部和数据两者都有呢,还是只有TCP头部而没有数据。当然,IP模块也不关心TCP的操作阶段,对于包的乱序和丢失也一概不知。
无论要收发的包是控制包还是数据包,IP对各种类型的包的收发操作都是相同的。
生成包含接收方IP地址的IP头部
IP地址由TCP模块告知的,而TCP又是在执行连接操作时从应用程序那里获得这个地址的,因此这个地址的最初来源就是应用程序。IP不会自行判断包的目的地,而是将包发往应用程序指定的接收方,即便应用程序指定了错误的IP地址,IP模块也只能照做。
生成以太网用的MAC头部
IP模块在生成IP头部之后,会在它前面再加上MAC头部。MAC头部是以太网使用的头部,它包含了接收方和发送方的MAC地址等信息。
MAC头部的开头是接收方和发送方的MAC地址,大家可以认为它们和IP头部中的接收方和发送方IP地址的功能差不多,只不过IP地址的长度为32比特,而MAC地址为48比特。此外,IP地址是类似多少弄多少号这种现实中地址的层次化的结构,而MAC地址中的48比特可以看作是一个整体。
MAC地址是在网卡生产时写入ROM里的,只要将这个值读取出来写入MAC头部就可以了。
在路由表中找到相匹配的条目,然后把包发给Gateway列中的IP地址就可以了。
既然已经知道了包应该发给谁,那么只要将对方的MAC地址填上去就好了,但到这里为止根本没有出现对方的MAC地址,也就是说我们现在根本不知道对方的MAC地址是什么。因此,我们还需要执行根据IP地址查询MAC地址的操作。
通过ARP查询目标路由器的MAC地址
在以太网中,有一种叫作广播的方法,可以把包发给连接在同一以太网中的所有设备。ARP就是利用广播对所有设备提问:“××这个IP地址是谁的?请把你的MAC地址告诉我。”然后就会有人回答:“这个IP地址是我的,我的MAC地址是××××。”(图2.19)不是这个IP地址的设备会忽略广播,什么都不回答。
ARP缓存中的值在经过一段时间后会被删除,一般这个时间在几分钟左右。这个删除的操作非常简单粗暴,不管ARP缓存中的内容是否有效,只要经过几分钟就全部删掉,这样就不会出问题了。当地址从ARP缓存中删除后,只要重新执行一次ARP查询就可以再次获得地址了。
以太网的基本知识
以太网是一种为多台计算机能够彼此自由和廉价地相互通信而设计的通信技术,它的原型如图2.22(a)所示。从图上不难看出,这种网络的本质其实就是一根网线。图上还有一种叫作收发器的小设备,它的功能只是将不同网线之间的信号连接起来而已。因此,当一台计算机发送信号时,信号就会通过网线流过整个网络,最终到达所有的设备。这就好像所有人待在一个大房间里,任何一个人说话,所有人都能够听到,同样地,这种网络中任何一台设备发送的信号所有设备都能接收到。
以太网3个性质:将包发送到MAC头部的接收方MAC地址代表的目的地,用发送方MAC地址识别发送方,用以太类型识别包的内容。
网络编程懒人入门(六):史上最通俗的集线器、交换机、路由器功能原理入门
将IP包转换成电或光信号发送出去
IP生成的网络包只是存放在内存中的一串数字信息,没有办法直接发送给对方。因此,我们需要将数字信息转换为电或光信号,才能在网线上传输,也就是说,这才是真正的数据发送过程。
负责执行这一操作的是网卡,但网卡也无法单独工作,要控制网卡还需要网卡驱动程序。
网卡并不是通上电之后就可以马上开始工作的,而是和其他硬件一样,都需要进行初始化。也就是说,打开计算机启动操作系统的时候,网卡驱动程序会对硬件进行初始化操作,然后硬件才进入可以使用的状态。
有人认为在网卡通电之后,ROM中的MAC地址就自动生效了,其实不然,真正生效的是网卡驱动进行初始化时在MAC模块中设置的那个MAC地址。在操作系统启动并完成这些初始化操作之后,网卡就可以等待来自IP的委托了。
网卡的ROM中保存着全世界唯一的MAC地址,这是在生产网卡时写入的。
网卡中保存的MAC地址会由网卡驱动程序读取并分配给MAC模块。
给网络包再加3个控制数据
- 数据信号、时钟信号好麻烦呀,还要叠加
网卡驱动从IP模块获取包之后,会将其复制到网卡内的缓冲区中,然后向MAC模块发送发送包的命令。接下来就轮到MAC模块进行工作了。
首先,MAC模块会将包从缓冲区中取出,并在开头加上报头和起始帧分界符,在末尾加上用于检测错误的帧校验序列(图2.24)。
用电信号来表达数字信息时,我们需要让0和1两种比特分别对应特定的电压和电流,例如图2.26(a)这样的电信号就可以表达数字信息。通过电信号来读取数据的过程就是将这种对应关系颠倒过来。
向集线器发送网络包
发送信号的操作分为两种,一种是使用集线器的半双工模式,另一种是使用交换机的全双工模式。(发送和接收同时并行的方式叫作“全双工”,相对地,某一时刻只能进行发送或接收其中一种操作的叫作“半双工”。)
首先,MAC模块从报头开始将数字信息按每个比特转换成电信号,然后由PHY,或者叫MAU的信号收发模块发送出去(根据以太网信号方式的不同,有些地方叫MAU(Medium Attachment Unit,介质连接单元),有些地方叫PHY(Physical Layer Device,物理层装置)。在速率为100 Mbit/s以上的以太网中都叫PHY。)。在这里,将数字信息转换为电信号的速率就是网络的传输速率,例如每秒将10 Mbit的数字信息转换为电信号发送出去,则速率就是10 Mbit/s。
接下来,PHY(MAU)模块会将信号转换为可在网线上传输的格式,并通过网线发送出去。以太网规格中对不同的网线类型和速率以及其对应的信号格式进行了规定,但MAC模块并不关心这些区别,而是将可转换为任意格式的通用信号发送给PHY(MAU)模块,然后PHY(MAU)模块再将其转换为可在网线上传输的格式。
PHY(MAU)模块的功能就是对MAC模块产生的信号进行格式转换。
网卡的MAC模块生成通用信号,然后由PHY(MAU)模块转换成可在网线中传输的格式,并通过网线发送出去。
在使用集线器的半双工模式中,一旦发生这种情况,两组信号就会相互叠加,无法彼此区分出来,这就是所谓的信号碰撞。这种情况下,继续发送信号是没有意义的,因此发送操作会终止。为了通知其他设备当前线路已发生碰撞,还会发送一段时间的阻塞信号,然后所有的发送操作会全部停止。
等待一段时间之后,网络中的设备会尝试重新发送信号。但如果所有设备的等待时间都相同,那肯定还会发生碰撞,因此必须让等待的时间相互错开。具体来说,等待时间是根据MAC地址生成一个随机数计算出来的。
当网络拥塞时,发生碰撞的可能性就会提高,重试发送的时候可能又会和另外一台设备的发送操作冲突,这时会将等待时间延长一倍,然后再次重试。以此类推,每次发生碰撞就将等待时间延长一倍,最多重试10次,如果还是不行就报告通信错误。
阻塞信号:以太网中发生碰撞时,为了告知所有设备而发送的一种特殊信号。
接收返回包
通知计算机的操作会使用一个叫作中断的机制。在网卡执行接收包的操作的过程中,计算机并不是一直监控着网卡的活动,而是去继续执行其他的任务。因此,如果网卡不通知计算机,计算机是不知道包已经收到了这件事的。网卡驱动也是在计算机中运行的一个程序,因此它也不知道包到达的状态。在这种情况下,我们需要一种机制能够打断计算机正在执行的任务,让计算机注意到网卡中发生的事情,这种机制就是中断。
首先,网卡向扩展总线中的中断信号线发送信号,该信号线通过计算机中的中断控制器连接到CPU。当产生中断信号时,CPU会暂时挂起正在处理的任务,切换到操作系统中的中断处理程序[插图]。然后,中断处理程序会调用网卡驱动,控制网卡执行相应的接收操作。
中断是有编号的,网卡在安装的时候就在硬件中设置了中断号,在中断处理程序中则将硬件的中断号和相应的驱动程序绑定。
现在的硬件设备都遵循即插即用[插图]规范自动设置中断号,我们没必要去关心中断号了,在以前需要手动设置中断号的年代,经常发生因为设置了错误的中断号而导致网卡无法正常工作的问题。
计算机中同时运行了很多程序,也会同时进行很多通信操作,因此收到的包也有可能是其他应用程序的。不过,即便如此也没问题,网卡不会关心包里的内容,只要按照以太类型将包交给对应的协议栈就可以了。接下来,协议栈会判断这个包应该交给哪个应用程序,并进行相应的处理。
将服务器的响应包从IP传递给TCP
响应从IP传递给TCP时,如果包的内容是应用程序数据,则返回确认接收的包,并将数据放入缓冲区,等待应用程序来读取;如果是建立或断开连接的控制包,则返回相应的响应控制包,并告知应用程序建立和断开连接的操作状态。
分片的包会在IP头部的标志字段中进行标记,当收到分片的包时,IP模块会将其暂存在内部的内存空间中,然后等待IP头部中具有相同ID的包全部到达,这是因为同一个包的所有分片都具有相同的ID。此外,IP头部还有一个分片偏移量(fragment offset)字段,它表示当前分片在整个包中所处的位置。根据这些信息,在所有分片全部收到之后,就可以将它们还原成原始的包,这个操作叫作分片重组。
TCP模块会根据IP头部中的接收方和发送方IP地址,以及TCP头部中的接收方和发送方端口号来查找对应的套接字[插图]。找到对应的套接字之后,就可以根据套接字中记录的通信状态,执行相应的操作了。