网络层的作用:在复杂的网络环境中确定一个合适的路径。
一.IP协议
IP存在的意义:IP地址提供一种能力,使得数据能够从主机B跨网络、可靠的送至主机A。
1.协议头格式
能够看出IP协议的格式与TCP协议存在很多相似之处,同样拥有4为首部长度和选项字段,更重要的是IP协议拥有16位总长度,表示整个IP数据报的大小,因此可以轻松将IP协议头进行分离。
8 位服务类型(Type Of Service): 3 位优先权字段(已经弃用), 4 位 TOS 字段, 和 1 位保留字段(必须置为 0). 4 位 TOS 分别表示: 最小延时, 最大吞吐量, 最高可靠性,最小成本. 这四者相互冲突, 只能选择一个. 对于 ssh/telnet 这样的应用程序, 最小延时比较重要; 对于 ftp 这样的程序, 最大吞吐量比较重要。
二.网段划分
IP 地址分为两个部分, 网络号和主机号:
- 网络号: 保证相互连接的两个网段具有不同的标识。
- 主机号: 同一网段内, 主机之间具有相同的网络号, 但是必须有不同的主机号。
IP地址是有用且有限的资源,所以需要经过合理的划分来进行分发,并通过精心的设计来快速高效的使用。
过去曾经提出一种划分网络号和主机号的方案, 把所有 IP 地址分为五类, 如下图所示:
- A 类 0.0.0.0 到 127.255.255.255
- B 类 128.0.0.0 到 191.255.255.255
- C 类 192.0.0.0 到 223.255.255.255
- D 类 224.0.0.0 到 239.255.255.255
- E 类 240.0.0.0 到 247.255.255.255
但是这种划分方法,导致了大量的地址浪费,于是又提出了新的划分方案CIDR:
- 引入一个额外的子网掩码(subnet mask)来区分网络号和主机号;
- 子网掩码也是一个 32 位的正整数. 通常用一串 "0" 来结尾;
- 将 IP 地址和子网掩码进行 "按位与" 操作, 得到的结果就是网络号;
- 网络号和主机号的划分与这个 IP 地址是 A 类、B 类还是 C 类无关;
来看一个划分子网的例子:
其中子网掩码是一个32位,前边连续一部分全1,剩余连续部分全0的正整数,子网掩码全为1的部分,即为网络号部分,全为0的部分为主机号部分。
通过IP地址与子网掩码按位与,得到的即为网络号,不难看出,上图所示的IP地址的主机号只有最后四位,因此其子网的地址范围即为:网络号+主机号从全0到全1之内的范围,但不包含全0和全1两个地址,因为这两个地址是特殊地址。
- 将 IP 地址中的主机地址全部设为 0, 就成为了网络号, 代表这个局域网;
- 将 IP 地址中的主机地址全部设为 1, 就成为了广播地址, 用于给同一个链路中相互连接的所有主机发送数据包;
- 127.*的 IP 地址用于本机环回(loop back)测试,通常是 127.0.0.1
IP 地址和子网掩码还有一种更简洁的表示方法,例如 140.252.20.68/28,表示 IP 地址140.252.20.68, 子网掩码的高 28 位是 1,也就是 255.255.255.240
三.私有和公网IP地址
如果一个组织内部组建局域网,IP 地址只用于局域网内的通信,而不直接连到 Internet 上,理论上使用任意的 IP 地址都可以,但是网络中规定了用于组建局域网的私有****IP 地址格式为:
- 10.*,前 8 位是网络号,共 16,777,216 个地址
- 172.16.*到 172.31.*,前 12 位是网络号,共 1,048,576 个地址
- 192.168.*,前 16 位是网络号,共 65,536 个地址
包含在这个范围中的, 都成为私有 IP, 其余的则称为全局 IP(或公网 IP);
私有IP不能出现在公网上,但是其可以在不同的私网中被重复使用,我们想要上网,都必须先接入指定的一个私网。
路由器能够构建子网,整个网络世界 = 公网 + 私网。
- 一个路由器可以配置两个****IP 地址 , 一个是 WAN 口 IP, 一个是LAN 口 IP( 子网 IP).
- 路由器 LAN 口连接的主机, 都属于当前这个路由器的子网中.
- 不同的路由器, 子网 IP 其实都是一样的(通常都是 192.168.1.1),子网内的主机IP 地址不能重复. 但是子网之间的 IP 地址就可以重复了。
- 每一个家用路由器, 其实又作为运营商路由器的子网中的一个节点. 这样的运营商路由器可能会有很多级, 最外层的运营商路由器, WAN****口 IP 就是一个公网 IP 了 .
- 子网内的主机需要和外网进行通信时, 路由器将 IP 首部中的 IP 地址进行替换(替换成 WAN 口 IP), 这样逐级替换,最终数据包中的 IP 地址成为一个公网 IP. 这种技术称为 NAT(Network Address Translation,网络地址转换).
四.路由
在复杂的网络结构中, 找出一条通往终点的路线,称为路由。
路由的过程, 就是一跳一跳(Hop by Hop) "问路" 的过程.
所谓 "一跳" 就是数据链路层中的一个区间. 具体在以太网中指从源 MAC 地址到目的MAC 地址之间的帧传输区间.
IP 数据包的传输过程也和问路一样:
- 当 IP 数据包, 到达路由器时, 路由器会先查看目的 IP;
- 路由器决定这个数据包是能直接发送给目标主机, 还是需要发送给下一个路由器;
- 依次反复, 一直到达目标 IP 地址;
那么如何判定当前这个数据包该发送到哪里呢? 这个就依靠每个节点内部维护一个路由表:
- Destination :目的网络地址;
- Genmask :子网掩码;
- Gateway :是下一跳地址,
- Iface :发送接口;
- Flags:的 U 标志表示此条目有效(可以禁用某些条目 ),G标志表示此条目的下一跳地址是某个路由器的地址,没有 G 标志的条目表示目的网络地址是与本机接口直接相连的网络,不必经路由器转发;
路由表可以使用 route 命令查看;
如果目的 IP 命中了路由表, 就直接转发即可;
路由表中的最后一行,主要由下一跳地址和发送接口两部分组成,当目的地址与路由表中其它行都不匹配时,什么该路由器中不存在你要发送的目的IP,就按缺省路由条目规定的接口发送到下一跳地址,也就是下一个路由器。
五.数据分片
在数据链路层中规定一个MTU长度 ,表示网络层传下来的数据必须是在MTU长度的大小之内的 ,这就导致如果数据过大,网络层必须将整个数据进行分片,才能传给数据链路层。
将数据分片,就代表着数据丢失的可能性大幅提升,在分片中,一个片丢失,就代表着整个报文的丢失,需要传输层重新发送数据。所以将数据分片,并不是网络转发的主流。但是分片又是必不可少的应用,下面就来看看,分片到底是如何进行的。
报头中的这三项,来为分片做服务:
- 16 位标识(id): 唯一的标识主机发送的报文. 如果 IP 报文在数据链路层被分片了, 那么每一个片里面的这个 id 都是相同的.
- 3 位标志字段: 第一位保留(保留的意思是现在不用)。第二位置为1 表示禁止分片, 这时候如果报文长度超过 MTU, IP 模块就会丢弃报文。第三位表示"更多分片", 如果分片了的话, 最后一个分片置为 0, 其他是 1, 是一个结束标记。
- 13位片偏移:表示各分片中有效载荷,相较于原始数据中有效载荷开头处的偏移量。除此之外,由于13位片偏移小于16位总长度,所以并不能完全表示分片的偏移量,实际偏移的字节数是这个值乘8得到的. 因此, 除了最后一个报文之外, 其他报文的长度必须是 8 的整数倍(否则报文就不连续了).
下面举个例子,来分享究竟是如何进行分片的:
通常情况下,MTU长度规定为1500字节,假如现有一个全长为3000字节的IP报文要进行分片:
- 第一片,是从IP报文开头,向后截取1500字节,该片包含20字节IP报头,1480字节有效载荷;
- 第二片,则是继续从原IP报文的1501字节开始,向后截取,此时需注意,每一个分片都必须包含IP报头部分的20字节长度,因为后续要进行拼接,所以第二片也必须由20字节IP报头,加1480字节有效载荷组成。
- 此时对于整个原IP报文,还剩余20字节的有效载荷,所以还需要第三片,即20字节IP报头,加20字节有效载荷组成。
当一串分片到来时,数据链路层收到头部分片即尾部分片,即判定收到了全部的IP报文,随后按照分片的偏移量进行升序排序,再判断其偏移量是否连续,进行二次判定,确认无误后,便进行组装,最终得到完整数据。