humid1ch blogs

本篇文章

手机用户建议
PC模式 或 横屏
阅读


Linux网络 2024 年 9 月 4 日

[TCP/IP] 网络层代表协议--IP协议介绍: IP协议 数据格式、子网划分、NAT和NAPT等 简单介绍

网络层的 IP协议 可以让主机拥有, 在网络中寻找主机的能力
TCP/IP 四层协议模型, 前面的文章, 已经通过介绍具体协议了解了前两层的功能:
  1. 应用层: HTTPHTTPS

    [TCP/IP] 初识应用层协议: 序列化与反序列化、编码与解码、jsoncpp简单食用…

    [TCP/IP] 应用层代表协议—HTTP协议 以及 HTTPS协议 分析合集

  2. 传输层: TCPUDP

    [TCP/IP] 传输层代表协议—UDP协议介绍 合集

    [TCP/IP] 传输层代表协议—TCP协议介绍 合集

本篇文章分析网络层代表协议: IP协议, 只以ipv4做介绍

IP协议

TCP/IP协议栈中:
  1. 应用层协议:

    主要做数据的处理工作, 包括: 序列化/反序列化, 协议处理, 分析读取完整报文等

  2. 传输层协议:

    更多与通信的场景有关, 数据传输是否需要保障可靠性, 通信是否需要建立连接等等

    通常TCP协议需要实现的最重要的工作是 保证数据在网络中传输的可靠性

那么网络层呢?
一般情况下, 向网络中发送数据是有指向性、目的性的. 比如, AB发信息, A向网络中发送数据, B就是A发送数据的目的地
而 网络是由多主机构成的, 数据并不总是能 直接发送到目的主机, 大多数情况 需要在网络中寻找目的主机
网络层 IP协议就可以让主机拥有, 在网络中寻找其他主机的能力
传输层封装的数据是要交付给网络层的, 网络层要实现的目的实际上也只有一个, 即 让主机拥有 能够将数据 从主机A发送到主机B的能力
因为IP协议能够让主机在网络中拥有唯一的IP地址, IP地址由网络号和主机号组成, 可以通过IP地址判断主机所在的网络
当主机B要向主机C发数据, 通过IP协议, 主机B就能将数据通过网络”传送”到主机C中
数据, 会在不同的路由器之间进行转发, 直到找到目的主机

主机: 拥有IP地址, 但不做路由控制的设备(有能力, 但不做)

路由器: 拥有IP地址, 并做路由控制的设备

节点: 网络中主机和路由器的统称

但是, IP并不提供传输可靠性的保障, 数据在网络中传输的可靠性是TCP协议实现的. 如果 IP数据包丢失, 同样也包含了TCP数据包的丢失, TCP协议就可以对数据传输可靠性实现保障
所以 想要数据可靠的传输到对端主机就需要结合TCP协议与IP协议
下面就来介绍一下, IP协议

IP协议格式

TCP协议相同, IP协议 以ipv4报头的标准长度为20字节:
分析一下ipv4协议报头的字段:
  1. [0, 3]: 4位版本, 用以区分IP协议的版本, 现在熟知的就是ipv4ipv6, 此字段就是用来区分协议版本的

    不得不说, 协议的设计者是真的有前瞻性, 早早的就将区分版本的字段给留了出来

  2. [4, 7]: 4位首部长度, 用于记录当前报头大小, 4位可表示0~15, 计算报头大小时 要*4, 所以报头大小范围为: 20~60字节

  3. [8, 15]: 8位服务类型(TOS)

    其中, 前三位[8, 10]为优先权字段, 但已经弃用

    [11, 14]为TOS字段, 只允许最多有一位设置为1, 分别表示: 最小延时, 最大吞吐量, 最高可靠性, 最小成本 (即, 需要实现什么属性)

    [15]保留字段, 没有使用

    此字段一般不需要进行设置, 除非真的有需求

  4. [16, 31]: 16位总长度(字节), 用于记录当前报文大小

  5. [32, 47]: 16位标识, 起 报文分片标识作用 (后面介绍)

  6. [48, 50]: 3位标志, 起 报文分片标志作用, 第一位保留不用 (后面介绍)

  7. [51, 63]: 13位片偏移, 起 报文分片整理作用 (后面介绍)

  8. [64, 71]: 8位生存时间(TTL), 标识IP报文在网络中的最长生存时间

    当数据被发送到网络中之后, 数据会经过许多次的路由转发

    正常情况下, 经过许多次的路由转发, 数据可以正常的被对端主机接收到

    但是在不正常的情况下, 可能因为一些情况对端无法接收数据, 数据可能在网络中不断路由, 即 数据在网络中游离. 此时, 就需要将数据丢弃掉, 防止占用网络资源

    此字段, 即 表示数据可在网络中路由转发的最长次数, 即 数据在网络中转发的跳数

    不可过大, 不可过小

  9. [72, 79]: 8位协议, 用于表示上层(传输层)使用协议, 用于分用

  10. [80, 95]: 16位首部校验和, 用于校验协议报头是否损坏

  11. [96, 127]: 32位源IP地址, 记录发送方主机IP地址, 很重要的字段

  12. [128, 159]: 32位目的IP地址, 记录目的主机的IP地址, 很重要的字段

  13. 至此, 一共[0, 159]位, 20字节, 即 ipv4首部标准长度为20字节

  14. 可能: [160, ...]: 选项, 一般情况下不会使用, 具体选项 具体分析

TCP/IP协议栈, 同主机不同层级之间传输数据, 存在三个操作: 封装、解包、分用

关于这三个操作的概念:

  1. 封装:

    TCP/IP协议中, 当上层需要将数据发送到下层时, 就要对数据进行封装

    封装, 即 在有效数据之前添加所用协议的报头

    然后, 才会将封装好的数据交付给下一层

  2. 解包:

    TCP/IP协议中, 当对端主机接收到完整数据时, 会对数据进行解包

    解包, 即 对接收到的数据, 将数据中 同协议的报头部分解析并去除掉

    比如, 如果传输层使用TCP协议发送数据, 那么接收方的传输层接收到数据之后, 会分析数据的TCP报头, 并将有效载荷(不包括协议报头的数据部分)提取出来

    然后, 才会将有效载荷交付给上层

  3. 分用:

    TCP/IP协议中, 当对端主机需要将数据从下层交付到上层时, 需要进行分用

    分用, 即 将有效载荷交付给上层中指定的协议, 因为相同协议才能正确处理数据中的协议报头

    因为, 同一层中会存在很多不同的、使用场景不同的协议, 所以需要解析出需要数据封装时所使用的协议, 才能将数据交付给上层

IP协议报头中:
[4, 7]位字段: 4位首部长度, 可以有效解决封装与解包的问题, 这个字段表示协议报头大小, 所以可以将数据中 协议报头有效解析出来, 进而可以解包
[72, 79]位字段: 8位协议, 可以有效解决分用的问题, 这个字段存储的内容是上层所使用的协议, 所以在向上层交付数据时, 读取此字段就可以解决分用问题

IP协议的分片

绝大多数的字段, 简单介绍下功能就能过理解字段的实际意义
不过有几个字段需要在解释一下:
这三个字段是比较重要的, 不过在解释作用之前, 要先了解一个概念: 分片
分片, 是IP协议可能会对传输层交付下来的数据进行的一种分割操作. 如果传输层交付过来的数据较大, IP协议会对传输层交付过来的数据进行分割, 并 会分别对分割出来的数据进行封装. 这个行为被称为分片
为什么会存在分片呢?
原因是, 数据链路层 因为物理设备问题, 会对数据的大小进行限制, 如果网络层交付的数据超出了限制大小, 数据链路层会直接将网络层交付的数据丢弃
所以, IP协议如果收到的上层数据过大, 就会对数据进行分片
而, 分片的存在就会造成一些问题, 因为对端主机会接收到分片数据:
  1. 对端主机如何确认数据是否分片?
  2. 如何确认分片数据之前是否属于同一数据?
  3. 如何确认已经完整的收到了同一数据的所有分片?
  4. 如何对已经分片的数据进行还原?
而这四个问题的答案, 都在这三个字段上
  1. 对端主机 如何确认数据是否分片?

    IP协议需要对数据进行分片时, 会对分片数据的IP协议报头的[48, 50]: 3位标志的对应位, 进行填充

    [48]位, 保留位 不被使用

    [49]位, 如果此位被设置为1, 表示禁止IP协议对数据分片. 此时, 当数据过大时, 将会被直接丢弃

    [50]位, 用以表示 是否有更多分片:

    当 此位被填充为1, 表示后面还有更多分片, 同时也表示 当前数据为分片数据

    当 此位被填充为0, 表示后面没有更多分片 或 表示此数据为非分片数据

    是否有更多分片是什么意思呢?

    当, IP协议对数据进行分片时, 会按照分先后顺序对数据进行分片

    如果, IP协议接收到6230字节的上层数据, 就会对数据进行分片, 可能会将[0, 1023] [1024, 2047] [2048, 3071] [3071, 4085] [4096, 5119] [5120, 6143] [6144, 6229]字节的数据, 均进行封装, 分片为个7最大不超过1500字节的IP数据报

    那么对于前6个分片数据, IP协议报头的第[50]位, 会被填充为1, 最后一个分片数据的 则会被填充为0

    所以, 当读取到IP协议报头的第[50]位为1时, 就说明还有属于同一数据的分片报文

  2. 对端主机 如何确认分片数据 之前是否属于同一数据?

    [32, 47] 16位标识, 就是用来标识 分片数据原来所属的数据的

    如果, IP协议需要对接收到的数据进行分片, 就会将这些分片的16位标识 均填充为相同的值

    这样, 对端主机读取时, 就能够识别到分片数据 所属的原数据

  3. 对端主机 如何确认已经完整的收到了同一数据的所有分片?

    首先, 对端必须接收到 报头第[50]位为0的分片数据

    然后就要根据[51, 63] 13位片偏移 确认是否有分片数据丢失了

    [51, 63] 13位片偏移, 填充的是 分片之后数据的首位置 相对 于原数据首位置的偏移量 再/8

    根据偏移量是否连续, 就可以确认是否完整的收到了同一数据的分片

    因为, [51, 63]为填充的是分片偏移量/8

    所以, 除了最后一个分片, 前面分片的大小需要为8的倍数

  4. 对端主机 如何对分片数据进行还原?

    根据[51, 63] 13为片偏移 进行还原

这是[32, 47]: 16位标识 [48, 50]: 3位标志 [51, 63]: 13位片偏移三个字段的作用, 均与分片有关
但, 分片是一种不好的行为
因为, IP协议并不能保证数据可靠性, 当对端主机 没有收到任意一个分片数据, 就会将其他所有 所属同一数据分片全部丢弃
这就意味着, 一旦对数据进行分片, 数据的丢包率就是所有分片丢包率的和, 即 分别越多 丢包率越高
所以, 一般情况下, 最好不要让IP协议对数据进行分片
但也不是直接禁止分片, 而是减少上层交付数据的大小, 所以 可以在传输层控制一下交付数据大小的上限

子网划分**

IP地址

IP地址, 在网络中是用来确定主机的
常规情况下, 每一台接入网络的主机都需要有一个唯一的IP地址, 这样能够在网络中确认唯一的主机, 然后才能通过IP地址实现不同主机之间的通信 (是IP唯一, 不是主机只拥有唯一的IP)
ipv4协议的IP地址为4字节, 日常通过点分十进制的方式表示, 比如: 192.168.5.111. 点分十进制表示IP地址, 每个点将分隔8位数据
所以192.168.5.111实际表示的是 11000000 10101000 00000101 01101111, 刚好四个字节
IP地址的这四个字节, 由两部分组成: 网络号+主机号. 网络号用于标识两个不同的网段, 主机号用于标识同一网段中的不同主机
网络号占用的位数越少, 主机号占用位就多, 主机号就能够越大, 就说明此网络中可以容纳的主机数就越多, 网络也就越大
比如, 192.168.5.111, 如果前24位都由网络号占用, 那么最后8位就由主机号占用, 那么192.168.5的这个网络中, 最多可以有0~255台主机
在网络中, 不同的主机是如何通过IP地址来快速地相互找到的呢?
网络中会存在许多的主机, 当两个主机需要发送数据时, 一定是知道双端主机的IP地址的
IP地址, 由两部分组成: 网络号 和 主机号
网络号是用来表示不同的网络的, 当数据被发送到网络中, 数据会在网络中的路由器之间路由
因为路由器也拥有自己的IP地址, 所以路由器也能够接收数据, 并且路由器会根据数据的IP报头中的 目的IP地址的网络号进行转发
网络号就像身份证的前6位一样, 是能够表示地区等信息的. 所以, 路由器之间进行网络信息同步之后, 是可以快速有效地进行数据转发的, 可以使数据快速的接近目标网络
直到数据被转发到目标网络之后, 再在网络内部 通过主机号找到目标主机

为什么路由器 通过网络号找目标网络 可以更快速地找到目标主机?

因为, 找目标网络可以按照网络排除一批主机, 而不是一个一个主机对比

IP划分方式

IP由两部分组成, 网络号和主机号
ipv4IP地址也就32位, 最多有256*256*256*256(4,294,967,296)IP地址, 并且是全球共用的
为了有效的、不浪费的使用IP地址, IP的网络号和主机号是有划分方式的
过去有一种划分方式, 将IP地址分为了5类:
  1. A类, 前8位为网络号, 且必须最高位必须为0

    包含IP地址为: 0.0.0.0127.255.255.255

    后24位为主机号, 那么A类网络中, 可包含主机数: 256*256*256(16,777,216), 用于大型网络

  2. B类, 前16位为网络号, 且最高两位必须为10

    包含IP地址为: 128.0.0.0191.255.255.255

    后16位为主机号, 那么B类网络中, 可包含主机数: 256*256(65536), 用于中型网络

  3. C类, 前24位为网络号, 且最高三位必须为110

    包含IP地址为: 192.0.0.0223.255.255.255

    后16位为主机号, 那么B类网络中, 可包含主机数: 256, 用于小型网络

  4. D类, 不做日常使用, 用于组播通信, 最高四位必须为1110

    包含IP地址为: 224.0.0.0239.255.255.255

  5. E类, 一般不用, 最高五位必须为11110

    包含IP地址为: 240.0.0.0247.255.255.255

前三类中, 需要哪一类, 就申请哪一类
此方法, 这会导致大量IP被浪费, 因为一申请A类B类, 就至少是65536IP
但实际上, 一个网段中通常是用不到这么多IP的. 被申请过的网络号又不能给其他人用, 所以就会造成很多IP浪费
所以, 就有了另外一种划分网络号和主机号方式, CIDR(Classless Interdomain Routing) 无类别域间路由:
  1. 引入一个叫 子网掩码(subnet mask) 的东西, 用于划分 网络号和主机号;

  2. 子网掩码是一个32位正整数, 子网掩码 由高位开始置1, 如果高位有N个1, 就表示对应IP高N位为网络号

    比如

    若存在IP以二进制表示: 11000000 10101000 00000101 10011101(192.168.5.157)

    若其高位前24位为网络号, 那么对应的子网掩码就应该是:

    11111111 11111111 11111111 00000000, 高24位置1

  3. 如果直到IP地址 和 子网掩码, 要求获取IP地址的网络号, 就可以 IP地址 & 子网掩码 计算

    子网掩码还有一种方式表示, IP/子网掩码位数

用子网掩码的方式划分IP, 与A、B、C类IP无关

子网掩码划分的优点

使用子网掩码相比类别划分, 有什么优点呢?
  1. 使用子网掩码, 可以更细化地划分IP地址

    比如 最小可以划分出 只有两台主机的网段, 只需要将子网掩码设置为11111111 11111111 11111111 11111110, 即 前31位是网络位

    那么, 一个网段中 最多只有两台主机

  2. 使用子网掩码, 可以更灵活地划分子网IP地址

    如果是类别划分, 就只有那三种类别可以在日常中使用, 网络号就只有8位、16位和24位三种情况

    而使用子网掩码划分, 可以随意地在合法范围内划分网络号的位数, 从1位到31位都可以

IPv4地址的限制

IPv4协议的IP地址是32位的, 最多也就40多亿的IP地址
而早在2021年, 全球的网民数量实际已经达到惊人的约49.7亿, 这只是网民数量, 还没有算上实际的设备数量
特别是 现在的移动互联网时代, 每个人手中可能有多部手机, 所以需要连接网络的设备远远不止49.7亿
再加上一些特殊的IP并不会被设备联网使用:
  1. 0.0.0.0, 代表当前主机所在的整个网络
  2. 127.*, 用于本机IP地址环回, 通常为127.0.0.1
  3. 255.255.255.255, 即 IP地址的32位全设置为1, 表示广播地址, 当向此IP发送数据时, 表示向同一子网中的所有主机发数据
即使 CIDR大大减少了IPv4地址的浪费, IP地址好像也完全不够用
不过, 有三种办法可以缓解这种情况:
  1. 动态分配IP地址

    即, 在设备不接入网络时 不分配IP地址, 在接入网络时, 动态分配IP地址

    所以, 同一个网卡设备, 每次接入网络时, IP可能并不会相同

  2. 使用IPv6协议

    IPv6协议的IP地址是128位的, IPv6地址的数量级是 10的38次方, 而IPv4只有10的9次方

    IPv6号称可以给地球上的每一粒沙子都分配一个IP地址

    所以, 使用IPv6好像可以没有后顾之忧的解决IPv4地址不足的情况

    不过, IPv6还没有完全发展起来, 并且与IPv4完全不兼容


    但是, 为什么现在绝大多数还是使用的IPv4呢?

  3. NAT技术*

    NAT技术, 是IPv4依旧坚挺的最大原因之一, 篇幅原因暂不介绍

公有IP和私有IP**

IP地址可以用来表示网络中主机的地址, 但 并不是所有IP都能出现在公网上
公有IP, 是连接在全球互联网上的IP, 在全球范围内是唯一的
私有IP, 则表示内部网络的IP, 不直接在全球公有互联网中进行路由, 即 私有IP不会出现在公网之中
不同的内部网络中, 私有IP地址是可以重复的
理论上, 私有IP的地址可以是任意的, 但RFC 1918规定了用于组建局域网的私有IP地址, 只能为一下这些:
  1. 10.*, 至少前8位为网络位
  2. 172.16172.31, 至少前12位为网络位
  3. 192.168.*, 至少前16是网络号
在这三个范围内的, 均被称为私有IP. 在公网中, 是看不到这三个范围的IP
即, 只要见到这三个范围内的IP地址, 就可以确定此IP是私有IP
比如:
172.19.4.141/20就是本机的私有IP, 前20位是网络号, 后12位是主机号
因为, 私有IP在不同的网络中可以重复, 即 这里一个网络中可以有 192.168.5.111, 另一个网络中也可以有 192.168.5.111, 只要能让私有IP也能够与全球的互联网通信, 就能够很大程度上解决IP不足的问题
NAT(Network Address Translation)技术, 就是 以公有IP结合私有IP的方式, 解决IPv4协议的IP不足问题的

NATNAPT 技术

因为IPv4协议的IP地址数量限制, 一般情况下电脑连接网线也好、WIFI也好, 操作系统自动分配的IP地址都是根据路由器分配的私有IP
  1. Windows可以在设置 或 通过ipconfig命令, 查看当前网络的IP:

  2. Linux也可以通过ifconfigip命令, 查看当前网络IP:

可以看到, IPv4IP地址大多都是私有IP地址
而, 私有IP是不允许出现在公网中的, 这就出现了一个疑问:
为什么操作系统分配的是私有IP, 但依旧能够通过网络访问公网信息?

NAT 网络地址转换


一般来说, 无论是城市还是乡村, 家庭网络都是由运营商搭建的
城市楼房, 一般在建筑阶段就会搭建好每家每户的网络线路布局, 在运营商开通网络服务之后, 网线就可以进行联网了
而乡村自建房, 可以直接和当地的运营商联系, 直接将网线接入家里, 再开通网络服务使用
总而言之, 一般情况下 网络服务都是由运营商来搭建的
运营商 能够配置家用路由器 使其接入运营商路由器的子网(一般都是私网), 然后 设备可以连接家用路由器进行上网
所以, 一般情况下, 家庭设备的IP地址, 都是根据 家用路由器所配置的 LANIP(子网IP) 进行分配的
这就是, 查看设备的IP地址 一般都为私有IP的原因
从直觉上, 家用路由器与运营商路由器配置好之后, 设备就可以通过家用路由器实现上网
但, 规定 私有IP不能出现在公网, 为什么操作系统分配的是私有IP, 但依旧能够通过网络访问公网信息? 这个问题, 还没有解决
NAT技术, 就能够解决这个问题
以上图为例:
假设左侧网络设备 A IP: 192.168.5.2 需要向 某个网页IP: 166.33.28.22 发送数据
设备A, 会在发送的数据报的IP报头 填充 源IP: 192.168.5.2 和 目的IP: 166.33.28.22
并且, 数据报不会直接发送到公网中, 不允许 也没有那个能力
因为网络是运营商提供的, 家用路由器连接的是运营商的网络, 不能绕过运营商直接访问公网, 所以:
  1. 数据报会从设备传输到家用路由器

    家用路由器接收到数据报, 会进行解包, 并重新封装

    不过, 由路由器重新封装的数据报的IP报头会发生变化

    路由器会将 数据报中 IP报头的源IP字段, 填充为路由器的WANIP: 10.1.1.2, 目的IP字段不变

    家用路由器, 会对比目的IP, 对新的数据报进行转发, 目的IP不在路由器所在局域网内, 是在公网中

    家用路由器, 就将数据报传输给 同一个局域网内的运营商路由器(IP: 10.1.1.*)

  2. 新数据报, 会从家用路由器传输到运营商路由器

    路由器会执行相同的操作, 将数据报的IP报头的源IP字段, 填充为路由器的WANIP: 122.77.241.4, 目的IP字段不变

    运营商路由器, WANIP已经是公网IP了, 已经可以访问公网了

    然后数据报就能够根据目的IP在网络中路由, 直到数据报达到目的网络

  3. 数据报, 在公网中路由, 达到目的网络

    目的网络做出处理之后, 再根据收到 数据报的源IP地址 进行响应

    由 家庭设备向公网中发送数据的过程就完成

类似上面的这个过程中
由 设备A发出的数据报, 源IP地址被 家用路由器 和 运营商路由器 转换为路由器自己的WANIP, 这样的源IP地址转换, 即为 NAT技术
这是, 从私网设备A 向 公网发送数据的简易过程
但是, 公网设备处理完数据, 需要响应数据回设备A, 又出现了一些问题:
  1. 设备AIP是 私有IP, 不允许出现在公网, 公网设备无法将设备A的IP 填充为 目的IP

  2. 公网设备收到的数据报中, 源IP是一个连接到公网的路由器的WANIP, 不是设备AIP

    即, 公网设备无法得知设备AIP, 更无法将设备AIP 填充为 目的IP

  3. 公网设备可以将响应数据报的目的IP填充为 收到的数据报的源IP

    但是, 如果目的IP为路由器的WANIP, 数据报就只能传输到路由器, 好像不能响应到设备A

  4. 如果, 一个私网内的许多设备 都向 同一个服务器发送请求

    那么, 这些设备发送的数据, 在服务器收到时, 源IP都会是相同的, 服务器无法好像无法辨别数据报来自哪些设备

    服务器 要响应数据, 好像也更没有办法分辨同一私网内的各个设备

要解决 将数据报从公网发送回私网设备 会出现的问题, 就需要另一个技术: NAPT

NAPT 网络地址端口转换

使用NAT技术, 可以让设备使用私有IP, 将数据发送到公网之中
但, 只有NAT技术, 无法满足 数据需要从公网响应回 使用私有IP的设备中 的需求
所以, 要与NAPT技术结合使用
NAPT全称是Network Address and Port Translation网络地址和端口转换, 是NAT技术的一种
端口, 是用于传输层协议的字段, 而TCP/IP协议栈, 就是根据IP:Port来确定网络中唯一主机上的唯一进程的
IP可以确定网络中的唯一主机, 但因为主机内的进程众多, Port才能够确定主机中唯一的网络进程
当使用私有IP的设备向公网中发送数据时, 其所经过的路由器并不只是简单的转换源IP地址, 还会转换源Port, 并在路由器内部构建起一张IP:Port映射表
举个例子:
  1. 设备A

    IP: 192.168.5.2

    存在进程P, Port: 8080

    进程P, 向公网中发送数据, IP报头中的源IP填充为192.168.5.2, TCP报头中的源Port填充为8080

  2. 数据报会经过各种路由器的转发, 在转发至连接到公网的路由器之前, 都会进行NAPT

  3. 当数据报发送到非公网路由器时

    1. 路由器会将数据报中, IP报头的源IP 转换为 路由器的WANIP

      除源IP之外, 路由器还会重新填充数据报的TCP报头的源Port

      这里Port是动态分配的, 在路由器里是唯一的

    2. 除了 转换数据报文中的 源IP 和 源Port 之外

      路由器还会构建一张表, 用于映射 转换前后的IPPort

      比如:

      转换前 IP:Port转换后 IP:Port
      192.168.5.2:808010.1.1.2:2255
      192.168.5.3:808010.1.1.2:2256

      经过这样的映射, 路由器就能够结合数据报文中的源IP和源Port两个字段, 确定数据的流向

使用私有IP的设备, 向公网发送数据时, 非公网路由器 会转换报文的源IP和源Port, 并构建转换前后IP:Port的映射表, 然后将数据转发至下一节点, 直到数据发送到公网中
当公网接收到数据并处理之后, 需要将数据响应回私网中的设备时
路由器可以查询 构建好的映射表, 来确定当前数据需要发送到哪个子网、哪个设备
这样就完成了 私网设备->公网 公网->私网设备 的一个来回的过程

NAT技术的缺点

  1. 当 私网设备从未向公网发送过数据时

    公网设备就无法直接向私网设备发送数据

    因为, 没有路由器构建过此设备的IP:Port转换映射表

  2. 转换映射表的生成和销毁, 都是需要一定的资源开销的

  3. 通信过程中, 一旦NAT设备发生异常, 建立好的所有TCP连接都会断开

路由表的查找

路由器进行数据转发, 是通过 数据报文中的目的IP 查询路由器内部的路由表 确定下一个节点的
路由表是什么呢?
路由表是一个存储有 网络路径信息 的数据结构, 无论是计算机还是路由器, 都有自己的路由表
路由表中存储了, 节点能够路由的所有网络, 一般包含有这些信息:
目标网络IP 子网掩码(Genmask) 网关(Gateway) 接口(Interface)
Linux中, 可以通过执行route -n来查看 已经建立好的路由表:
Windows中, 可以通过route PRINT -4来查看 已经建立好的路由表:
路由器中, 也存储有自己的一张路由表
当路由器需要转发数据时, 就通过查询路由表信息选择数据的下一个路由网络
查询的方式也很简单, 数据的目的网络IP & 路由表中的子网掩码, 就能计算出目标网络
对比目标网络是否一致, 就能够实现查询路由表

路由是根据网络号对比实现的, 所以 每一跳能够实现直接排除一整个网络, 拥有极高的效率