引言
之前协议栈系列的文章讲解了 连接,收发网络包,断开连接这些操作协议栈模块的处理,但是协议栈是上层 接下来会 委托ip模块进行真正的处理。
网络包
网络包的组成
网络包由头部的控制信息和头部后面的传输数据组成。
控制信息代表了包要发往的目的地,传输数据就是要发送的数据
网络包的转发
ip模块会将包发送到最近的一个转发设备中,转发设备会根据头部的控制信息找到下一个要发送的转发设备:转发设备内部存储了一张表记录了每一个地址对应的发送方向,也就是按照头部里记录的目的地址在表里进行查询下一个要发送的转发设备在哪,然后到达下一个转发设备时还是一样的查询然后发送,一次一次的转发最后就会到达目的地
这些对于所有的通信方式都是适用的,只不过tcp/ip会更加复杂
转发设备
前面讲过子网中有路由器和集线器两种不同的转发设备,它们在传输网络包时有着各自的分工。集线器是按照以太网规则进行传输的,路由器是按照ip规则;头部信息中会携带mac头部和ip头部
- 路由器根据目标地址判断下一个路由器的位置(内部有一个路由表 存储的是该服务器ip最近的路由器的ip地址)
- 集线器在子网中将网络包传输到下一个路由(集线器也有一张表叫做以太网协议表 因为是按照mac地址工作的 所以这张表记录这对应的mac地址的发送方向)
大致流程
发送方将服务器的ip地址写入到ip头部中;ip协议先根据服务器ip查找到要发送的下一个路由器ip地址,在找到这个ip对应的mac地址填充到mac头部, 委托以太网协议进行发送;
接下来包被发送的时候会经过集线器 集线器通过ip协议填充的mac地址可以找到下一个路由器并转发到对应的路由器(内部有一张表);
下一个路由器收到之后抹除mac头部地址,再根据ip协议找到下一个路由器ip 在找到对应的mac地址填充到mac头部委托以太网协议再发送
以此类推 就到达了服务器地址。
每个路由器的目的就是查找到下一个路由器的ip转换成mac填充到包的mac头部,并通过集线器转发到下一个地址直至传输到服务器
图示:
以太网的部分也可以替换成其他的东西,例如无线局域网、ADSL、FTTH等,它们都可以替代以太网的角色帮助IP协议来传输网络包。只不过填充的就不是以太网依赖的mac头部信息了,当使用除以太网之外的其他网络进行传输时,MAC头部也会被替换为适合所选通信规格的其他头部。
ip模块发送网络包
添加网络包的头部控制信息
虽说是tcp模块委托ip模块发送的数据,但是ip模块也是借助网卡委托的那些转发设备发送的(之后分析网卡的时候讲解)
因此包收发操作的起点是TCP模块委托IP模块发送包的操作。
这个委托的过程就是TCP模块在数据块的前面加上TCP头部信息并把服务器ip整个传递给IP模块, 这部分就是tcp模块发送网络包的内容。

之后ip模块通过tcp头部发送的服务器ip填入到ip头部。并查询下一个转发设备的ip和mac地址mac头部。
IP头部中包含IP协议规定的、根据IP地址将包发往目的地所需的控制信息(服务器ip地址);MAC头部包含通过以太网的局域网将包传输至最近的路由器所需的控制信息。(下一个路由器的mac地址)
tcp模块在原有数据的基础上添加tcp头部信息,ip模块在tcp头部前面再添加ip头部和mac头部。
ip头部中添加发送方ip地址
ip地址本质上是分配给网卡的,但是计算机中已经集成了网卡因此也可以说计算机的ip地址。
一个网卡对应一个ip地址,计算机上有多个网卡时就要选择该使用哪块网卡(用哪个ip地址)进行网络包的发送。
IP头部的“接收方IP地址”填写通信对象的IP地址。
发送方IP地址需要判断发送所使用的网卡,并填写该网卡的IP地址。
路由器使用ip协议通过内部的表找到下一个路由器的ip,协议栈的ip模块也是使用的ip协议因此他们两个操作应该是相同的。
ip模块通过使用路由表来确定使用哪个ip地址进行发送
可以通过route print命令来显示路由表,委托网卡硬件发送数据
路由表查找规则
第一列destnation表示服务器地址
gateway代表要发送的下一个路由器的ip地址也叫网关
interface代表使用哪个网卡发送方哪个ip地址发送包到gateway
如果gateway和interface一样,泽代表是最终目的地
- 首先通过目的地ip地址找到路由表中的network destination 找到对应的条目(如目的地ip为195.6.32那么找到的destination可能就是195.6
- 如果gateway和interface一样,那么路由器直接发送到destnation接收方的ip地址即可
通过interface选择要使用的网卡ip地址发送包到gateway(下一个路由器)如果两个相同代表当前路由器就可以直接发送给接收方ip了不需要再接住下一个路由器转发了(也就是说处于同一个子网中)
添加协议号
表示包的内容是来自哪个模块的。
TCP模块委托的内容,则设置为06(十六进制),如果是UDP模块委托的内容,则设置为17(十六进制),这些值都是按照规则来设置的。现在的浏览器中都是使用的tcp发送的因此设置为06
添加mac头部
MAC头部是以太网使用的头部,它包含了接收方和发送方的MAC地址等信息。
可以看到mac地址是48比特,而ip地址是32比特。
mac头部的以太类型和ip地址中的协议号类似
可以认为以太网类型后面就是以太网包的内容,而以太类型就表示后面内容的类型。以太网包的内容可以是IP、ARP等协议的包, 它们都有对应的值,这也是根据规则来确定的。
ip协议类型是0800(十六进制)
发送方mac地址由于上面已经判断了该使用哪块网卡发送(interface)因此直接从网卡的rom中获取即可(生产网卡时会把mac地址写入到网卡rom)。
接受方ip地址(这里指的是ip模块传递下来的ip地址,不是服务器的ip地址,通过路由表中gateway项确定)确定了,那怎么才能拿到接受方的mac地址呢?
IP模块根据路由表Gateway栏的内容判断应该把包发送给谁。
arp协议转换ip地址为mac地址
以太网中有一种广播的方式可以向处于同一子网中的所有设备发送包。
比如arp会问这个ip地址是谁的,把max地址告诉我。那个这个设备就会就行回答是我的并告知自己的mac地址
arp缓存
每次查询mac地址都广播的话,网络中会出现很多很多的arp包。因此会有一块arp缓存的内存空间用于存放查找过得mac地址。
每次查询mac地址时先看缓存有没有,有就取出直接使用;如果没有则进行广播发送arp包。
arp缓存失效
ip地址是会改变的,这时候对应的mac地址就不能用了会发生错误发送到错误的接收方。因此会隔几分钟删除缓存的内容
ip模块对应的发送接受
发送
添加网络包控制信息对应于图中的1发送。接下来说明2发送包会到网络硬件
可能是插在计算机主板上的板卡,也可能是笔记本电脑上的PCMCIA卡,或者是计算机主板上集成的芯片,不同形态的硬件名字也不一样,它们统称为网卡。
网卡接收到的网络包数据是0和1的数字组成的,网卡会将数字转换成电信号或者光信号通过网线发送出去。到达转发设备,转发设备在进行转发最终到达服务器。
接受
接受网络包也是同样的流程,通过转发设备给到网卡,网卡将电信号转换成数字信号给到ip模块;然后ip模块将去除mac头部和ip头部(也就是只剩tcp头部和数据)的包交给tcp模块。
ip模块并不关心自己转发的包是否包含tcp头部或者真实数据也不关心tcp模块的操作是否成功,他只负责转发操作。
无论要收发的包是控制包还是数据包,IP对各种类型的包的收发操作都是相同的。
职责界定
通过上面的了解可以看出ip模块完成了所有的操作交给网卡的是已经封装好的包,网卡只负责接包发送包
这样的好处是对于除IP以外的其他类型的包也是一样,如果在交给网卡之前完成打包,那么对于网卡来说,发送的操作和发送IP包是完全相同的。这样一来 ,同一块网卡就可以支持各种类型的包。
再看看接受也是一样的。不管这个是什么类型的包,只负责交给对应的网络模块即可不用关心这个包是什么类型。