网络层协议 —— IP协议
目录
0.前言
1.IP协议的格式
2.IP地址
2.1IP地址的划分
国际间IP地址的划分
公有IP
私有IP
特殊的IP地址
国内IP地址的划分
2.2IP地址不足问题
2.3IP地址的功能
2.4如何使用IP地址
2.5IP地址的构成
3.网段划分
以前的方案
现在的方案
4.认识宏观网络
5.路由
路由器
路由表
NAT技术
路由的过程
6.总结
0.前言
对于网络层IP协议的学习,我们不能局限于IP协议本身,而应通过学习IP协议建立对整个网络的宏观认识。
1.IP协议的格式
咱们先认识认识IP协议的格式:
各字段的简单说明:
4 位版本号:表明了IP协议的版本,对于 IPv4 来说,就是 4。
4 位首部长度:表明了IP协议报头的总长度。
- 需要注意的是,首部长度只有四个比特位,能表示的最大值是15,但是协议报头中的固定长度都有20个字节,所以4位首部长度需要带上基本单位 —— 4字节。
- 这样一来,4位首部长度能表示的最大值就是60字节了。
8 位服务类型:其中有3 位优先权字段(已经弃用),4 位 TOS 字段,和1 位保留字段(必须置为 0)。
- 4 位 TOS 分别表示最小延时、最大吞吐量、最高可靠性、最小成本。这四者相互冲突, 只能选择一个。
- 对于 ssh、telnet 这样的应用程序,最小延时比较重要,对于 ftp 这样的程序, 最大吞吐量比较重要。
16 位总长度:表明IP报文的总长度。
- 包括报头和数据。
16 位标识:唯一的标识主机发送的报文。
- 如果 IP 报文在数据链路层被分片了,那么每一个片里面的这个 id 都是相同的。
3 位标志字段:
- 第一位保留(保留的意思是现在不用, 但是还没想好说不定以后要用到)。
- 第二位置为 1 表示禁止分片,这时候如果报文长度超过 MTU(数据链路层所能传输的最大数据单元),IP 模块就会丢弃报文。
- 第三位表示"更多分片",如果分片了的话,最后一个分片置为 0,其他是 1。类似于一个结束标记。
13 位分片偏移:表明分片相对于原始 IP 报文开始处的偏移。
- 其实就是在表示当前分片在原报文中处在哪个位置。实际偏移的字节数是这个值除8
得到的。- 因此,除了最后一个报文之外,其他报文的长度必须是 8 的整数倍(否则报文就不连续了)。
8 位生存时间:数据报到达目的地的最大报文跳数。
- 一般是64。每次经过一个路由,该值就会减1,如果报文中该值一直减到 0 还没到达,那么该报文就会被丢弃。
- 这个字段主要是用来防止出现路由循环。
8 位协议: 表示上层协议的类型。
- IP协议根据8位协议表明将数据交给上层的哪个协议。
16 位头部校验和:使用 CRC 进行校验,来鉴别头部是否损坏。
32 位源地址和 32 位目标地址: 表示发送端和接收端。
选项:用于表明一些特殊用途(不细谈哈)。
2.IP地址
在IP协议的报头中,我们可以很清楚的看到两个字段 —— 32位源IP地址和32位目的IP地址。可以说这两个字段是IP协议中最重要的两个字段了,需要重点学习。
2.1IP地址的划分
国际间IP地址的划分
公有IP
进行IP地址的划分首先要分配给各个国家,各个国家分配到的IP地址在国家之间使用。这些IP地址称为公有IP地址。通常是一段区间。
私有IP
如果一个组织内部组建局域网,需要使用私有IP地址,私有IP 地址只能用于局域网内的通信,而不直接连到因特网上。理论上 使用任意的 IP 地址都可以,但是 RFC 1918 规定了用于组建局域网的私有 IP 地址只能使用一下几种
- 10.*:前 8 位是网络号,共 16,777,216 个地址。
- 172.16.*到 172.31.*:前 12 位是网络号,共 1,048,576 个地址。
- 192.168.*:前 16 位是网络号,共 65,536 个地址
包含在这个范围中的,都称为私有 IP,其余的则称为全局 IP(或公网 IP)。
如果把IP地址比作一块大蛋糕的话,其中一部分被单独拿出去用于组件局域网了,剩下的才能被分配给各个地区和组织。
特殊的IP地址
- 将 IP 地址中的主机地址全部设为 0,就成为了网络号,代表这个局域网。
- 将 IP 地址中的主机地址全部设为 1,就成为了广播地址,用于给同一个链路中相互连接的所有主机发送数据包。
- 127.*的 IP 地址用于本机环回(loop back)测试,通常是 127.0.0.1。
国内IP地址的划分
当我们国家从国际上分配到了一定区间的IP地址之后,需要分配给国内的各个地区和组织使用,下图为部分地区和组织分配到的IP地址。
2.2IP地址不足问题
我们都知道IP地址是32个比特位构成的数字,32个比特位所能表示数字大约是43亿个左右,而 TCP/IP 协议规定,每个主机都需要有一个 IP 地址,那是不是意味着世界上只有43亿台设备能够接入网络?实际上,由于一些特殊的 IP 地址的存在,数量远不足 43 亿。另外 IP 地址并非是按照主机台数来配置的,而是每一个网卡都需要配置一个或多个 IP 地址。这也就必然导致IP地址不足的问题。
这时候有三种方式来解决:
- 动态分配 IP 地址:只给接入网络的设备分配 IP 地址。因此同一个 MAC 地址的设备,每次接入互联网中,得到的 IP 地址不一定是相同的。
- NAT 技术(后面谈)。
- IPv6:IPv6 并不是 IPv4 的简单升级版。这是互不相干的两个协议,彼此并不兼容。IPv6 用 16 字节 128 位来表示一个 IP 地址,但是目前 IPv6 还没有普及。
2.3IP地址的功能
在我们的日常生活中,如果你想给你的朋友写信,你必须要知道并填写朋友的地址,只有这样,邮局在派发信件的时候才能有目的地进行派发,才能确保信件准确的送到朋友的手上。当然了,你写信的时候也需要表明自己的地址,只有这样,朋友才知道是谁给他发的信,未来,朋友想要回信的时候,才能填充你的地址。
在网络通信的世界中,信息的发送亦是如此。当两台主机需要通信的时候,发送方必须表明自己的地址和接收方的地址,只有这样才能确保信息发送到指定的主机上,接收方的主机才知道信息是哪台主机发给他的,才能进行准确的响应。这个地址就是IP地址。
所以IP地址的功能就是用来进行主机定位。
2.4如何使用IP地址
问题来了,网络通信的过程中,发送方应该如何表明接收方的地址呢?
举个栗子:
当我们想要通过浏览器访问CSDN的时候,需要输入www.csdn.net,这时候浏览器就会将该域名解析为csdn服务端程序所在主机的IP地址和端口,假设是123.132.212.231:80,这时候我们不就表明了我们想要访问那一台主机上的哪一个服务了吗?也就是说,对方的地址我们是提前知道的。
从代码角度理解:
当我们使用socket编程接口编写客户端网络通信程序的时候,是不是要先填充一个叫做 struct sockaddr_in的结构体对象,该类型的对象中有一个sin_addr.s_addr的成员,其实这个成员的值就是目标主机的IP地址。
所以我们可以这样理解,当我们填充该成员的时候,其实就是在填充IP协议的32位目的IP,具体细节由操作系统自动完成了。
说明一下:对于32位源IP地址的填充是属于通信的细节,对于通信的细节,操作系统为自动为我们实现,也就是说,32为源IP地址的填充是由操作系统自动完成的。
2.5IP地址的构成
IP地址可以分为两个部分:网络号和主机号。
- 网络号:保证相互连接的两个网段具有不同的标识。
- 主机号:同一网段内,主机之间具有相同的网络号,但是必须有不同的主机号。
不同的子网其实就是把网络号相同的主机放到一起。
如果在子网中新增一台主机,则这台主机的网络号和这个子网的网络号必须一致,但是主机号绝对不能和子网中的其他主机重复 。
也就是说,网络号用来标识不同的子网,主机号用来标识不同的主机,网络号+主机号就可以标识一个子网中的一台主机。
所以我们现在知道了,通过合理设置主机号和网络号,就可以保证在相互连接的网络中,每台主机的 IP 地址都不相同,才能保证数据准确的发送到指定的主机上。那么问题来了,如何管理子网内的IP地址呢?
- 有一种技术叫做 DHCP(Dynamic Host Configuration Protocol,动态主机配置协议),能够自动的给子网内新增主机节点分配 IP 地址,避免了手动管理 IP 的不便。
- 一般的路由器都带有 DHCP 功能,因此路由器也可以看做一个 DHCP 服务器。
3.网段划分
我们已经知道了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
随着 因特网 的飞速发展,这种划分方案的局限性很快显现出来,大多数组织都申请 B 类网络地址, 导致 B 类地址很快就分配完了,而 A 类却浪费了大量地址。
例如,申请了一个 B 类地址,理论上一个子网内能允许 6 万 5 千多个主机,A 类地址的子网内的主机数更多。然而实际网络架设中,不会存在一个子网内有这么多的情况。因此大量的 IP 地址都被浪费掉了。
现在的方案
于是,针对上述情况提出了新的划分方案,称为 CIDR(Classless Interdomain Routing)。
- 引入一个额外的子网掩码(subnet mask)来区分网络号和主机号。
- 子网掩码也是一个 32 位的正整数,通常用一串 "0" 来结尾。
- 将 IP 地址和子网掩码进行 "按位与" 操作,得到的结果就是网络号。
- 因此,网络号和主机号的划分与这个 IP 地址是 A 类、B 类还是 C 类无关。
举个例子:
可见,IP 地址与子网掩码做与运算可以得到网络号,主机号从全 0 到全 1 就是子网的地址范围。
IP地址和子网掩码还有一种更简洁的表示方法,例如 140.252.20.68/24,表示 IP 地址为
140.252.20.68,子网掩码的高 24 位是 1,也就是 255.255.255.0。
4.认识宏观网络
说明一下:网络的建设其实是运营商精心设计好的。运营商在设计上需要划分出一个个的子网。在行动上需要挖地道、铺光纤、甚至还需要帮你拉网线。
我们可以这样理解下面这张图:
最小的网络我们可以看做是家里的网络,同一网段下的主机之间是可以直接通信的,但是,要想和其他子网中的主机通信就需要通过路由器了,这里的路由器我们称之为家庭路由器。所以,路由器可以横跨两个网络。家庭路由器可以和家庭路由器连接,也可以和更大的主机(提供服务的主机)连接,此时它们之间就构成了更大的子网,更大的子网之间需要进行通信,需要通过功能更强大的运营商路由器进行连接。这些功能更强大的路由器连接的可能是市和市之间的网络,市和市之间的网络通过市间路由器连接又共同组成了省级别的网络,省级别的网络又通过省间路由器进行连接便构成了整个国家的网络,国家和国家之间的网络通过国际路由器进行连接便构成了全球的网络。
所以,网络通信的世界其实是由一个个的子网构成的。不同的子网之间通过路由器连接,路由器之间又可以构成更大的子网。当子网上升到一定程度就变成了公网。
所以不同子网的主机进行通信的时候,需要通过路由器进行路由转发,将信息送到指定的主机上。
5.路由
路由器
数据路由的过程需要依靠路由器来完成,路由器的主要工作是完成不同网络中数据的转发。
• 一个路由器需要横跨两个网络,所以需要配置两个 IP 地址,一个是 WAN 口 IP,一个是 LAN 口 IP(子网IP)。
• 路由器 LAN 口连接的主机,都从属于当前这个路由器的子网中。
• 不同的路由器,子网 IP 其实都是一样的(通常都是 192.168.1.1)。子网内的主机IP地址不能重复。但是子网之间的 IP 地址就可以重复了。
• 每一个家用路由器,其实又作为运营商路由器的子网中的一个节点。这样的运营商路由器可能会有很多级,最外层的运营商路由器,WAN 口 IP 就是一个公网 IP 了。
路由表
路由器内部都会维护一个路由表,用来记录与该路由器相连的通信设备。
Destination:表示目的网络地址。
Genmask:表示子网掩码。
Gateway:表示下一跳的地址。
Iface:表示发送接口。
Flags:中的 U 标志表示此条目有效(可以禁用某些条目)。
G标志:表示此条目的下一跳地址是某个路由器的地址,没有 G 标志的条目表示目的网络地址是与本机接口直接相连的网络,不必经路由器转发。
NAT技术
子网内的主机需要和外网进行通信时,路由器将 IP 首部中的源IP地址进行替换,替换成 WAN 口 IP,这样逐级替换,最终数据包中的 源IP 地址成为一个公网 IP。这种技术称为 NAT(Network Address Translation,网络地址转换)。
通过NAT技术,局域网中的IP地址不会出现在公网上,也就是说,不同局域网中的IP地址可以重复,这样也就变相的增加了IP地址的数量。
注意:不同局域网中的IP地址可以重复,那么IP地址就不能唯一的标识全网中的一台主机,准确的说,应该是私有IP不能唯一的标识一台主机,但是公网IP是可以的。
路由的过程
所谓路由的过程其实就是发送方发送的数据在网络中发往目标主机的过程。
假如主机A需要向主机B发送消息,首先主机A会拿着自己的子网掩码和目的IP做按位与运算,发现目的IP的网络号不是自己所在的网络,于是将报文交给路由器,由路由器决定将该报文发给谁。
路由器怎么知道将数据发给谁呢?
这个时候,路由器就会查自己的路由表。具体就是,拿着目标IP地址和路由表中记录的子网掩码进行按位与操作,如果得到的网络号为该子网掩码对应的IP地址,就将报文转发给下一跳地址所对应的设备。如果查询完所有的子网掩码都没有找到对应的目标网络,则发送给缺省路由器,缺省路由器根据他自己的路由表决定数据发给谁,循环往复,直到数据交给目标主机。
在发送数据的过程中,路由器进行数据的转发的时候,会进行NAT转换技术,也就是将报文中的源IP地址更换成自己的WAN口IP。
整个路由的过程类似于问路的过程,报文不断的向路由器询问,我下一站怎么走,路由器就告诉他怎么走。
6.总结
不同主机进行网络通信时,需要能够找到对方,网络层的IP协议便提供了这种能力,主要依靠IP地址。
网络的世界是由一个个的子网组成的,子网是由一台台通信设备组成的,所以IP地址需要有能力标识不同的子网和子网中的主机,所以IP地址具有网络号和主机号。
为了划分IP地址的网络号和主机号,人们引入子网掩码,通过IP地址和子网掩码进行按位与操作,得到网络号,从而决定将数据发送给哪个网络,当然,这个过程是通过主机 or 路由器中的路由表来完成的。
对于子网的构建,IP地址中专门划分出了一批私有IP用来组建局域网,不同的局域网中的IP地址可以相同,这样就提高了IP地址数量的上限,解决了IP地址不足的问题,但是私有IP不能出现在公网上,这个时候就需要引入NAT技术进行路由转发时的地址替换。如果只是使用部分IP地址专门用来组建局域网,但是不提供NAT技术的话,IP地址不足的问题无法依旧无法解决。
数据路由的过程需要依靠路由器,路由器通过查找路由表决定数据应该交给谁,同时使用NAT技术避免私有IP出现在公网上。