地址范围
前缀划定子网
IP 地址配置在网络接口上。接口是系统收发网络包的入口;同一台机器可以有多个接口,也可以有多个 IP 地址。
IPv4 地址有 32 个二进制位,通常写成四段十进制数。子网是一组共享地址前缀的地址;/24 表示前 24 位是网络部分,剩下 8 位可变化。这种“地址/前缀长度”写法叫 CIDR(无类别域间路由)表示法。[1]
在普通 /24 子网里,192.168.1.0 是网络地址,192.168.1.255 是广播地址,通常不分给主机。判断同子网时,必须带上前缀长度,不能只看“前三段像不像”。
两台主机是 192.168.1.20 和 192.168.1.200,配置相同前缀。请填“是”或“否”。
用 /24 时同子网:;用 /25 时同子网:。
/24 覆盖末段 0–255,所以同子网。/25 把范围一分为二,20 落在 0–127,200 落在 128–255,所以不同子网。
深入:同子网就一定能连通吗?
同子网只说明地址如何划分。还要有可用的链路、正确配置,以及允许通信的防火墙。跨子网的包按路由表转发;路由表是一组“目标地址范围 → 下一跳”的规则,默认网关是没有更具体路由时使用的下一跳路由器。
普通广播子网常用 2^(32−前缀长度)−2 算可分配地址数;/31 点对点链路与 /32 单地址有特殊用途,不套这个减二公式。
接收范围
监听决定接收范围
端口是 TCP、UDP 等传输协议里的数字字段。TCP 与 UDP 是两种传输协议,端口空间分别计算;本页只跟踪 TCP。套接字(socket)是应用向操作系统收发数据的接口;TCP 服务绑定本地地址和端口,再进入监听(LISTEN)状态,等待新连接。[2]
127.0.0.1 是回环地址,包在当前网络环境内返回自己;0.0.0.0 用于监听时,表示当前网络环境的所有本地 IPv4 地址。客户端应连接真实目标地址,不应把它当成服务器地址。
图中假定 192.168.1.20 配置在本机。只绑定这个具体地址时,仅匹配发往它的连接。匹配监听不等于一定可达,还要检查路由与防火墙。
服务只监听 127.0.0.1:18080。另一台机器连接这台服务器的 192.168.1.20:18080,把端口号写对就够了吗?为什么?
不够。目的端口相同,但目的 IP 不匹配监听地址。直接接收局域网连接,需要绑定局域网接口地址或所有本地 IPv4 地址;同时确认路由与防火墙允许。
要在当前网络环境接收发往所有本地 IPv4 地址的 TCP 18080 连接,应监听哪里?
回环监听只匹配当前网络环境里的回环目的地址。
这是单个本地接口地址,不代表其他本地 IPv4 地址。
0.0.0.0 在绑定监听时是通配地址。它覆盖当前网络环境的所有本地 IPv4 地址,但不会替你放行防火墙,也不会跨入另一个容器的网络环境。
深入:为什么两个服务都能用端口 80?
监听匹配要看协议、本地 IP 和端口,也要看所在网络命名空间。网络命名空间是 Linux 隔离接口、路由和套接字的机制;不同容器通常有各自的网络命名空间,所以可以分别监听自己的 TCP 80。同一环境、同一协议下,相同地址和端口的重复绑定通常会冲突;复用套接字的特殊配置超出本页范围。
IPv6 的回环地址是 ::1,通配监听地址是 ::。IPv6 监听是否同时接收 IPv4,受套接字选项和系统设置影响,不能只看一个“80”就下结论。
Linux 实验 · 约 3 分钟
实测地址与监听
在同一台 Linux 机器上开两个终端。需要 iproute2(提供 ip、ss)和 Python 3。以下在编写环境实测;普通用户即可完成。
先看地址。ip addr 会列出接口地址;下面加 -4 和 dev lo,只看 IPv4 回环接口。[3]
你应看到 inet 后的地址和前缀。接口序号、MTU 等字段可能不同;lo 是回环接口的名字。要找自己的局域网地址,运行 ip -4 addr,看其他接口的 inet 行,别照抄示意图的 IP。
终端 A:在一个可公开的空目录运行临时 HTTP 服务。它会把该目录的文件提供给请求方;此处只绑定回环,不提供给局域网。
python3 -m http.server 18080 --bind 127.0.0.1
终端 B:先运行 ss -lnt,再加过滤条件,只看本次实验。-l 只看监听,-n 保留数字地址与端口,-t 只看 TCP。[3]
重点读 Local Address:Port。这里的 Peer Address:Port 为 0.0.0.0:*,表示监听套接字还没有固定对端,不能据此推断“对外监听”。队列列的数值可能因系统和程序版本而异。
可在终端 B 用浏览器访问 http://127.0.0.1:18080/,或运行下面的客户端;本环境实际输出为 200,表示 HTTP 请求成功。
在终端 A 按 Ctrl + C 停止,再改为:
python3 -m http.server 18080 --bind 0.0.0.0
此命令会监听所有本地 IPv4 地址。请只在可信网络、空目录里短时测试;它不修改路由或防火墙。测完按 Ctrl+C 关闭,不要把敏感文件目录作为服务目录。
终端 B 再执行同一条 ss 命令。下面是第二次实测输出:
两次输出的对端列相同。请解释:为什么第二次监听范围更大?你依据的是哪一列?
应看本地地址列。127.0.0.1 只绑定回环,0.0.0.0 绑定所有本地 IPv4 地址。对端列的通配符描述尚未固定的对端,不能替代本地绑定信息。
- 指出 Local Address:Port
- 区分回环绑定与通配绑定
- 没有把对端通配符当作对外开放证据
若提示地址已占用,先停止自己先前的服务,或统一换成其他空闲端口。此实验只验证监听和回环 HTTP 请求,没有实测跨机器访问或 NAT。
出站与回包
NAT 改写包地址
私网地址可在各自网络内重复使用,不能作为全球唯一地址在公网路由。RFC 1918 保留了下面三段;172. 开头并不全是私网。[4]
| 前缀 | 完整范围 |
|---|---|
10.0.0.0/8 | 10.0.0.0–10.255.255.255 |
172.16.0.0/12 | 172.16.0.0–172.31.255.255 |
192.168.0.0/16 | 192.168.0.0–192.168.255.255 |
网络地址转换(Network Address Translation,NAT)在转发时改写地址。多台私网主机共享一个外部 IP 时,常同时转换 TCP/UDP 端口,称 NAPT(网络地址端口转换)。下面展示这种常见模型。[5]
图中把“IP:端口”称为端点。源端点表示谁发来,目的端点表示发给谁。公网角色采用专供文档的地址,不能拿来测试实际联网。[6]
- 客户端发起连接,源端口 40000 由教学场景设定。先猜:离开网关时,源与目的哪个端点会变?
- 网关建立转换记录,把内网源端点映射为外部端点;62001 是示意分配值。
- 发向服务器的包改了源 IP 和源端口,目的端点保持不变;服务器看到的是网关的外部端点。
- 服务器把回包发给 203.0.113.10:62001。先猜:网关凭什么知道回给内网哪台机器?
- 网关根据这条连接的转换记录,把回包目的端点还原;回包的源仍是服务器。
- 包交回 192.168.1.20:40000,这次请求与响应形成闭环。
图中包含端口改写,但 NAT 不保证每次都换端口。只要不冲突,转换设备可能保留原端口。不能把图中的 62001 当成 Docker 或路由器的固定分配规则。
深入:NAT 和防火墙分别负责什么?
NAT 负责地址或端口改写,防火墙负责按规则允许或丢弃流量。没有现成映射时,外部新连接通常无法仅凭一个共享外部 IP 确定内网接收者;静态映射可以提供明确入口,但仍需防火墙允许。NAT 不等于访问控制,也不等于加密。
本图省略链路层、校验和与具体连接跟踪实现。路由负责选择下一跳,NAT 负责改写字段;跨子网转发并不必然需要 NAT。
衔接模块 5
映射提供明确入口
要让外部主动访问内网服务,可以预先指定映射。目的地址转换(Destination NAT,DNAT)将到达入口的包改写为发往内部服务。普通路由转发可以保留目的 IP;下面的映射会改写目的端点。
到达宿主机 · TCP · 教学设定
源 192.168.1.50:40000
目的 192.168.1.20:8080
↓ 按映射规则改写目的 IP 与端口
转发给容器 · TCP
源 192.168.1.50:40000
目的 172.18.0.2:80
Docker 的 -p 8080:80 表示“宿主机端口 8080 → 容器 TCP 端口 80”,默认向宿主机所有地址发布。Docker 的 bridge(桥接)网络默认使用 NAT;容器出站常使用宿主机地址。[7]
这条映射不会启动应用,也不会修改应用的监听地址。容器内应用若只监听自己的 127.0.0.1:80,转发到容器接口地址 172.18.0.2:80 的包仍不匹配该监听。
按图 6 的规则,客户端应连接宿主机端口 ;经过目的改写后,包的目的端口是 。
客户端知道宿主机入口 8080。Docker 把它映射到容器端口 80,应用要在容器可接收该包的地址上监听 80。这两个端口分别属于两侧端点。
可复制的 Docker 小实验
未实测 编写环境没有 Docker,以下提供命令和预期现象,不提供虚构输出。适用 Docker Engine 29.x 的默认 bridge / NAT 配置;需要 Docker、联网拉取镜像,以及空闲的本机 18081 端口。
在宿主机终端 A 运行。--rm 表示服务退出后自动删除容器;-p 127.0.0.1:18081:8000 把入口限制在宿主机回环地址。容器内 Python 监听 0.0.0.0:8000,匹配容器自己的接口地址。[7][8]
docker run --rm -p 127.0.0.1:18081:8000 python:3.13-alpine \
python -m http.server 8000 --bind 0.0.0.0
宿主机终端 B 运行同样的 Python 客户端,但连接宿主机入口:
python3 -c 'import urllib.request; print(urllib.request.urlopen("http://127.0.0.1:18081/").status)'
预期现象(未实测):服务就绪后,客户端应打印 200(HTTP 成功状态码)。这是按 Python HTTP 服务行为推导的预期,维护者待补实际输出。容器服务的日志应出现本次请求。在终端 A 按 Ctrl+C 停止,容器随后自动删除;拉取的镜像会保留。
默认 Linux bridge 模式下,Docker 会为容器准备虚拟网络连接,并为端口发布添加转发与防火墙规则;容器删除后清理相关资源。首次使用还可能初始化默认网桥。本实验无需 --privileged,也不要求你手工修改 iptables;不要改成 --network host。
深入:为什么 ss 不足以证明端口已映射?
ss 查看当前网络命名空间的套接字。Docker 端口发布可能通过内核转发规则实现,也可能涉及用户态代理;宿主机不一定有一个与你预想完全相同的监听套接字。是否发布可用 docker ps 看 PORTS,再用实际请求验证。
Docker Desktop 的 Linux 容器运行在虚拟机中,宿主机入口由 Desktop 的转发层接入;宿主机上的 ip/ss 不等同于 Linux Docker 主机内部视图。rootless(以非 root 运行的 Docker)也有额外转发机制。图 6 仅用于理解 Linux bridge 默认 NAT 的目的字段变化;routed 等网络模式可不使用 NAT,具体实现留到模块 5。参见 Desktop 网络说明与 rootless 模式说明。
回顾与迁移
沿端点逐层检查
- 看地址范围:IP 要结合前缀;
/25比/24小。 - 看本地监听:协议、绑定地址和端口一起判断;
ss的对端列不决定监听范围。 - 看转换前后:出站 NAT 改源,回包按记录还原目的;入口映射指定内部目的端点。
- 看真实路径:入口映射、应用监听、路由与防火墙都满足,连接才可能成功。
图 5 的服务器回包到达网关时,目的端点是 203.0.113.10:62001。还原并发回内网后,哪个端点正确?
这是回包在网关外侧的目的端点,内网客户端不使用这个地址。
这是服务器端点;在回包里它是源,不是目的。
网关按转换记录,把外部端点对应回原发起者 192.168.1.20:40000。回包的目的端点还原了,源端点仍为服务器 198.51.100.20:80。
为模块 5 做准备:Docker 端口已经发布,容器内服务却只监听 127.0.0.1。请用“包的目的端点”和“监听地址”解释为什么仍可能访问失败。
端口发布把流量送到容器接口地址和目标端口。容器自己的回环地址只接收本环境的回环流量,无法匹配送到接口地址的连接。要检查应用绑定地址,并继续排查路由和防火墙。
- 指出宿主机入口与容器目的端点不同
- 指出回环监听不匹配容器接口地址
- 没有把发布端口当作已经启动或重新配置应用
来源
核对日期:2026-11-03。Docker 部分按 Engine 29.x 的默认 bridge / NAT 场景讲解。Linux 输出来自本环境 iproute2 6.15.0 与 Python 服务实验;Docker 实验未实测。
- RFC 4632 §3.1:IPv4 前缀与 CIDR 表示法。
- Linux ip(7):地址、端口、回环与通配绑定语义。
- ip-address(8)、ss(8):地址显示、监听选项和过滤表达式。
- RFC 1918 §3:三段私有 IPv4 地址空间。
- RFC 3022 §2.2、§3:NAPT 与双向转换。
- RFC 5737 §3:文档示例地址,不用于真实公网访问。
- Docker:Port publishing、Bridge network driver:端口发布、回环绑定、默认 NAT 与其他网关模式。
- Docker:docker container run:
--rm、-p的语义。 - Python 3.13 http.server 文档:命令行端口、绑定地址与目录服务;Docker Official Images 的 Python 标签登记:实验镜像标签依据。