1. IP协议基本了解
1.1 基本概念
主机:有IP,但不能进行路由控制。
路由器:既有IP又可以路由控制。
节点:主机和路由器的统称。
1.2 头格式
4位版本号:ipv4
4位头部长度:代表有多少个32个比特位,即length*4字节数,4bit表示最大数字是15,即首部最大长度是60字节。
8位服务类型:3位优先权字段(弃用),4位tos字段,1位保留字段(要重置为0);4位tos表示最小延迟、最大吞吐量、最高可靠性、最小成本,这四个互相冲突,根据不同场景选一个。
16位总长度:IP数据报整体占多少字节。
16位标识:唯一的标识主机发送的报文,如果IP报文在数据链路层被分片了,那么每一个分片里面的这个id都是相同的。
3位标志字段:第一位保留(现在不用,以后说不定用到),第二位为1是表示禁止分片,这时候如果报文长度超过MTU,IP就会丢弃报文,第三位表示“更多分片”,如果分片了的话,最后一个分片置为1,其他是0,类似结束标记。
13位分片偏移:是分片相当于原始IP报文开始处偏移,其实就是在表示当前分片在原报文中处于哪个位置,实际偏移字节数就是这个值*8(以8字节为单位),所以除了最后一个报文,其他报文长度必须为8的整数倍。
8位生存时间(TTL):数据报到达⽬的地的最大报文跳数,一般是64,每经过一个路由,TTL-=1,如果减到0没有送到,就丢弃这个报文,主要防止路由循环。
8位协议:表示上层协议类型,6=TCP,17=UDP,1=ICMP。
16位头部校验和:使用CRC进行校验,判断头部是否损坏。
32位源地址和32位目标地址:表示发送端和接收端。
IP地址用点分十进制来表示,每个部分取值0~255
选项:可选,0~40 字节。用于记录路由、时间戳等,实际很少用。
数据:上层协议数据(TCP/UDP 报文)。
2. 地址管理
2.1 网段划分
IP地址主要两个部分:网络号和主机号。
网络号:保证相互连接的两个网段具有不同的标识。
主机号:同一⽹段内,主机之间具有相同的⽹络号,但是必须有不同的主机号。
子网其实就是把网络号相同的主机放到⼀起。
如果在子网中新增一台主机,则这台主机的⽹络号和这个子网的网络号⼀致,但是主机号一定不能和子网中的其他主机重复。
通过设置网络号和主机号,可以保证在相互连接的网络中,每台主机的IP不同,但是如果手动管理IP地址很麻烦,这需要DHCP技术,功能简单来说就是自动给网络里的新主机分配IP地址,不用手动管理。路由器有带有DHCP功能,因此可以路由器看成是一个DHCP服务器。
过去提出划分网络号和主机号的方案,如图:
| 类别 | 范围 | 用途 |
|---|---|---|
| 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 | 组播(Multicast) |
| E 类 | 240.0.0.0 ~ 247.255.255.255 | 保留(实验用) |
但是如果按照这样的情况划分,很多组织选择B类地址,B类很快分配完,导致A类大量浪费,如果申请B类地址,理论上一个子网可以容下6万5千多个主机,但是不存在一个子网那么多个主机情况,因此大量IP也浪费掉了。
针对以上提出新的划分方案:CIDR
- 引入一个额外的子网掩码(subnet mask)来区分网络号和主机号
- 子网掩码也是一个32位的正整数,通常用一串 "0" 来结尾
- 将IP地址和子网掩码进行 "按位与" 操作, 得到的结果就是网络号
- 网络号和主机号的划分与这个IP地址是A类、B类还是C类无关
划分子网案例:
划分子网的例子1
| 项目 | 十进制表示 | 十六进制表示 |
|---|---|---|
| IP 地址 | 140.252.20.68 | 8C FC 14 44 |
| 子网掩码 | 255.255.255.0 | FF FF FF 00 |
| 网络号 | 140.252.20.0 | 8C FC 14 00 |
| 子网地址范围 | 140.252.20.0 ~ 140.252.20.255 |
划分子网的例子2
| 项目 | 十进制表示 | 十六进制表示 |
|---|---|---|
| IP 地址 | 140.252.20.68 | 8C FC 14 44 |
| 子网掩码 | 255.255.255.240 | FF FF FF F0 |
| 网络号 | 140.252.20.64 | 8C FC 14 40 |
| 子网地址范围 | 140.252.20.64 ~ 140.252.20.79 |
将IP地址 140.252.20.68 以二进制表示:10001100.11111100.00010100.01000100
其子网掩码 255.255.255.0二进制表示:11111111.11111111.11111111.00000000
将两者进行“与”运算得到网络号:10001100.11111100.00010100.00000000 十进制表示为140.252.20.0
2.2 特殊IP
- 将IP地址中的主机地址全部设为0,就成为了网络号,代表这个局域网
- 将IP地址中的主机地址全部设为1,就成为了广播地址,用于给同一个链路中相互连接的所有主机发送数据包
- 127.*的IP地址用于本机环回(loop back)测试,通常是127.0.0.1
2.3 IP地址数量限制
ipv4有32位,那么一共有2^32次方个IP地址,大概是43亿左右,按照网卡算的IP数量,一个网卡设置1个或多个IP地址。
CIDR一定程度减缓了IP的不够用的问题(只是提高利用率,减少浪费,并没有提高使用数量上限),可以通过以下方法解决:
- 动态分配IP:上网分配,不上不分配,早期这个方案可行,现在依旧紧张。
- NAT技术:网络地址映射(核心),下面细说。
- ipv6:是ipv4的升级,但是两者没有联系,ipv6是128为表示地址的。
2.4 私有IP地址和公网IP地址
| 私有IP | 公网IP | |
| 定义 | 局域网内部使用,不能直接上互联网 | 全球唯一,可直接上互联网 |
| 谁分配 | 你自己(路由器/DHCP) | 运营商(ISP) |
| 是否唯一 | 内网唯一,不同内网可重复 | 全球唯一 |
| 能否直接上网 | ❌ 需要 NAT 转换 | ✅ 直接可访问 |
| 费用 | 免费 | 要花钱买/租 |
- 10.*,前8位是网络号,共16,777,216个地址
- 172.16.到172.31.,前12位是网络号,共1,048,576个地址
- 192.168.*,前16位是网络号,共65,536个地址,包含在这个范围中的,都成为私有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,网络地址转换)。
- 如果希望我们自己实现的服务器程序,能够在公网上被访问到,就需要把程序部署在一台具有外网IP的服务器上。这样的服务器可以在阿里云/腾讯云上进行购买。
3. 路由选择
在复杂的网络里找到一条通向终点的路,这个“跳”的动作相当于问路。
IP数据包的传输就是问路的过程:
- 当数据包达到路由器时,路由器查看目的IP
- 路由器决定这个数据包传给下个路由器还是目标主机
- 一次反复知道到达目的IP地址
怎么判断数据包发送哪里?依靠节点里维护的一个路由表
第1步:主机A 发货(查自己的路由表)
主机A 要发数据给主机B。它先查自己的路由表,发现“主机B”不在本地局域网内。
于是,它把数据包发给自己的默认网关——路由器A。
(图中:快递员说“发给路由器A即可,再往后可以咨询路由器A”)
第2步:路由器A 中转(查路由表)
路由器A 收到包,发现目标 IP 是主机B。
它查自己的路由表,发现“去主机B”的下一跳应该是路由器B。
于是,路由器A 把包转发给路由器B。
(图中:路由器A 看着手里的路由表,指向了主机B的方向)
第3步:路由器B 送达(查路由表)
路由器B 收到包,再次查自己的路由表。
发现主机B 就连接在自己的某个端口(局域网)上,或者已经到达最终目的地。
路由器B 直接把包交给主机B。
4. NAT机制
4.1 网络转发
有两个设备A,B
(1)如果A,B在一个局域网,直接按照IP转发即可,在内网里IP也不会重复
(2)如果A,B在两个不同的局域网,默认无法直接通信,必须经过各自网关和路由器的转发。如果路由不通,才会禁止/丢包。
(3)如果A是内网IP设备,B是外网IP设备,A可以主动访问B,B不能主动访问A(如果A已经访问B了,B可以原路返回找到A)
(4)如果A和B都是外网IP,则不涉及NAT直接转发
4.2 NAT传输过程
基础设定:
内网 A 互联网 内网 B ┌──────────────┐ ┌──────────────┐ │ 主机A │ │ 服务器B │ │ 192.168.1.100│ │ 10.0.0.5 │ └──────┬───────┘ └──────┬───────┘ │ │ ┌──────┴───────┐ ┌──────┴───────┐ │ 路由器A │ │ 路由器B │ │ LAN:192.168.1.1│ │ LAN:10.0.0.1 │ │ WAN:113.1.1.1 │ │ WAN:203.1.1.1│ └──────┬───────┘ └──────┬───────┘ │ │ └────────────────── 互联网 ──────────────────────────────┘| 设备 | IP |
|---|---|
| 主机 A(内网 A) | 192.168.1.100:50000 |
| 路由器 A LAN | 192.168.1.1 |
| 路由器 A WAN | 113.1.1.1 |
| 服务器 B(内网 B) | 10.0.0.5:80 |
| 路由器 B LAN | 10.0.0.1 |
| 路由器 B WAN | 203.1.1.1 |
步骤:
(1)主机A发出请求:
源 IP:192.168.1.100 源端口:50000 目标 IP:203.1.1.1(路由器 B 的公网 IP) 目标端口:8080由于目标IP不是同一个子网下的,所以需要发送给网关(路由器A的lan口:192.168.1.1)。
(2)路由器 A 做地址转换
路由器A收到包:
源 IP:192.168.1.100:50000 目标 IP:203.1.1.1:8080进行地址转换:
源 IP:192.168.1.100 → 113.1.1.1 源端口:50000 → 60000(分配新端口)记录在NAT表里:
113.1.1.1:60000 ↔ 192.168.1.100:50000从路由器A发出去的包:
源 IP:113.1.1.1:60000 目标 IP:203.1.1.1:8080(3)数据包在互联网上转发
逐跳转发到达路由器B
(4)路由器 B 做地址转换
路由器B收到包:
源 IP:113.1.1.1:60000 目标 IP:203.1.1.1:8080查看端口映射:
203.1.1.1:8080 → 10.0.0.5:80目的地址转换:
目标 IP:203.1.1.1 → 10.0.0.5 目标端口:8080 → 80转发到服务器B:
源 IP:113.1.1.1:60000(不变) 目标 IP:10.0.0.5:80