>

写给完全零基础的读者。读完这篇,你能看懂别人说的「你的端口没开」「走的是内网 IP」「这个是 UDP」到底在讲什么,并且会一套能直接上手敲的网络排查命令。

> >

全文只用类比 + 命令 + 表格,不涉及任何「需要你去查的」东西。所有命令都能直接复制到 Linux 终端(macOS 基本通用)。


0. 先给你一个贯穿全文的例子

后面所有内容,我们都围绕下面这个真实场景展开,你带着它读,最后会发现所有概念其实是在描述同一件事:

>

你坐在家里,笔记本连上了家里路由器(WiFi),打开浏览器输入 https://example.com,页面就出来了。

> >

而你的笔记本,其实拿到的是一个 192.168.1.2 这种「内网地址」——它根本没有真正的公网门牌号,为什么却能访问全世界?

这一问,就是整篇教程要回答的东西。我们一层一层剥开。


1. IP 地址:互联网上每个设备的「门牌号」

1.1 IPv4 长什么样

IP 地址(Internet Protocol address)就是互联网上给每个设备发的一张门牌号。没有它,数据包就不知道要送到哪台机器。

最常见的 IPv4 长这样:

192.168.1.2

它由 4 段数字组成,用点 . 隔开,每段是 0255 之间的一个数。这叫「点分十进制」,你不用背,只要记住这个外形:

段1234
值19216812
范围0255025502550255
>

类比:192.168.1.2 就像「某小区(192)某栋(168)某单元(1)某房间(2)」。四段合起来,全世界唯一地指向一台设备。

IPv4 只有 4 段,理论上限大概 42 亿个地址。早年够分,现在手机、摄像头、服务器一多,地址就不够用了——所以有了 IPv6(下面一句话带过)。

1.2 公网 IP vs 内网 IP(局域网)

这是新手最容易混的地方,务必分清。

概念是什么例子能不能直接从外网访问
公网 IP真正「登记在册」、全球唯一的门牌号203.0.113.7✅ 能
内网 IP(私有 IP)只在你家里/公司这一小片网络(局域网)内有效的门牌号192.168.1.2❌ 不能(需 NAT,见第 5 节)

局域网(LAN)就是「你家里/公司这一小片」:你的电脑、手机、电视、打印机,都接在同一个路由器下,组成一个局域网。它们互相之间用内网 IP 通信,比如 192.168.1.2 直接找 192.168.1.3 传文件,根本不用经过外网,速度极快。

内网 IP 有几段「保留段」,全世界谁都能这么用(所以你家、我家、公司都用 192.168.1.x 不冲突):

内网段范围
192.168.0.0/16192.168.0.1 ~ 192.168.255.254(家用最常见)
10.0.0.0/810.0.0.0 ~ 10.255.255.255(大公司常用)
172.16.0.0/12172.16.0.0 ~ 172.31.255.255
>

关键结论:你家里所有设备的 IP 都是 192.168.x.x 这种内网地址,它们自己并不是公网门牌号。那它们怎么上网?——靠路由器的 NAT(第 5 节详解)。这就是我们开头那一问的答案。

怎么查自己的 IP?

# 查本机所有网卡的 IP(会看到 192.168.1.2 这种内网地址)
ip addr
# 或者简写
ip a

(ip addr 的输出在第 8.1 节详细解读。)

1.3 IPv6(一句话带过)

IPv6 是为了解决 IPv4 地址不够而生的,地址长到 128 位(16 进制,用冒号分隔),比如 2400:3200:0001:0000:0000:0000:0000:0001,可用地址几乎无限。你偶尔会在 ip addr 里看到 inet6 fe80::... 就是它,知道它存在即可,本文其余部分都以 IPv4 为例。


2. 子网掩码、网关、CIDR:一个「/24」说清楚

这三个词经常一起出现,看着唬人,其实一句话能讲清。

2.1 子网掩码:告诉你「门牌号的哪几位是小区号」

还记得 192.168.1.2?其实它藏了两个信息:

  • 哪部分是「小区」(网络号)
  • 哪部分是「房间号」(主机号)

子网掩码(Subnet Mask)就是用来划这条线的。它的长这样:

255.255.255.0

把 IP 和掩码「按位与」一下(你不用会算,记住结果就行):

IP:      192.168.1.2
掩码:    255.255.255.0
────────────────────
网络号:  192.168.1.0     ← 前面三段被保留 = 「这是哪个小区」
主机号:  2              ← 最后一段 = 「小区里第几个房间」
>

类比:掩码就是「小区号的长度」。255.255.255.0 意味着「前 3 段是小区号,最后 1 段是房间号」。

2.2 CIDR:/24 就是掩码的简写

每次写 255.255.255.0 太累,于是有了 CIDR 记法(无类别域间路由):直接写 192.168.1.0/24。

这个 /24 的意思是:掩码有 24 个连续的 1(二进制里)。

CIDR等价掩码说明
/24255.255.255.0家用最常见
/16255.255.0.0更大的网络
/32255.255.255.255精确到单个 IP

所以 192.168.1.0/24 一句话讲清:

>

「这是一个网络号为 192.168.1.0、掩码 24 位(即 255.255.255.0)的子网,它包含 192.168.1.1 ~ 192.168.1.254 共 254 个可用主机地址(.0 是网络号、.255 是广播地址,都不能分给设备)。」

>

一句话记忆:/24 = 一个最多装 254 台设备的小区。/16 是更大的城,/32 就精确到某一个人。

2.3 网关(Gateway):小区的大门

网关就是「小区通往外面世界的唯一出口」,也就是你的路由器在内网那一侧的地址。

  • 你电脑 192.168.1.2,网关通常配成 192.168.1.1。
  • 你要访问 192.168.1.3(同小区)→ 直接找,不用过网关。
  • 你要访问百度(外网)→ 数据包先送到网关 192.168.1.1,由路由器再转发出去。
>

类比:网关 = 小区大门的保安亭。同小区串门不用出门;去外面,一律先过保安亭。

查看你的网关:

# 查看路由表,default 那一行的 via 后面就是你的网关
ip route
# 典型输出:
# default via 192.168.1.1 dev eth0   ← 192.168.1.1 就是网关
# 192.168.1.0/24 dev eth0

3. 端口:门牌号后面,还有一串「房间号」

3.1 端口是什么

只靠 IP 还不够。 因为一台服务器上同时跑着很多服务:网页服务、数据库、SSH 远程登录……数据包到了这台机器(门牌号),还得分发给「具体哪个程序」去处理。

端口(Port)就是这台机器上「程序/服务的房间号」,范围 0 ~ 65535(一共 65536 个)。

>

类比(重点):

>
  • IP = 楼的门牌号(192.168.1.2 这栋楼)
  • >
  • 端口 = 楼里的房间号(22 是「远程登录室」、80 是「前台接待室」)
  • >
  • 一个完整地址 = 门牌号 + 房间号,写作 IP:端口,例如 192.168.1.2:22。
> >

你打电话找人,号码是楼,分机号是端口。同一个 IP,不同端口,是不同的服务。

补充几个常识:

  • 01023 是「知名端口」(well-known ports),被系统/标准服务占用,普通用户程序一般不用这么小的号。
  • 一个程序启动时会「监听(listen)」某个端口,等着别人来连。
  • 同一台机器上,同一个端口同一时间只能被一个程序占用(所以才会出现第 9 节说的「端口被占用」)。

3.2 常见端口速查表

先背下这张表,后面看命令输出、排查问题全靠它:

端口服务通俗说明协议
22SSH安全远程终端(命令行登服务器)TCP
80HTTP网页(明文,不安全)TCP
443HTTPS网页(加密,带 https://)TCP
3306MySQL最常见的关系型数据库TCP
5432PostgreSQL另一款主流关系型数据库TCP
6379Redis内存缓存 / KV 存储TCP
8080HTTP 备用 / 应用默认后端服务、Tomcat 等常用,开发调试最爱TCP
9000Grafana / FastCGI / 自定义监控面板、一些 Go 服务、自定端口TCP
>

记不住没关系,80/443 是网页,22 是 SSH,3306/5432 是数据库,6379 是缓存——记住这几个,日常工作就够用了。

查本机现在哪些端口在被监听(命令输出详解见第 8.2 节):

ss -ltnp

4. TCP vs UDP:慢递 vs 快递

数据在网上传输,主要靠两种「传输方式」:TCP 和 UDP。它们是同一层(传输层)的两个兄弟,性格完全不同。

4.1 TCP:可靠、有序、但慢的「慢递」

TCP(传输控制协议)是面向连接的:通信前要先「握手」确认对方在,传数据时保证不丢、不乱、不重复。

它的招牌动作是三次握手(建立连接):

客户端                          服务器
  │   ① 我要连你 (SYN)            │
  │ ───────────────────────────▶  │
  │   ② 好的,我收到 (SYN+ACK)    │
  │ ◀───────────────────────────  │
  │   ③ 那开始吧 (ACK)            │
  │ ───────────────────────────▶  │
  │        连接建立,开始传数据      │

特点:

  • 可靠:丢了的包会自动重传。
  • 有序:到达顺序和你发的顺序一致。
  • 慢:握手 + 重传 + 确认,开销大。
  • 适合「不能丢一个字」的场景。

典型场景:网页(HTTP/HTTPS)、SSH、邮件、文件下载、数据库连接(MySQL/PostgreSQL/Redis)——凡是要保证完整的,基本都是 TCP。

4.2 UDP:快速、不可靠的「快递」

UDP(用户数据报协议)是无连接的:不用握手,来一句发一句,不保证送达、不保证顺序。

特点:

  • 快:没握手、没确认、没重传,开销极小。
  • 不可靠:包丢了就丢了,顺序可能乱。
  • 适合「丢一帧无所谓、要快」的场景。

典型场景:DNS 域名解析、视频直播、语音通话(VoIP)、在线游戏、实时行情。

4.3 TCP vs UDP 对比表

维度TCPUDP
连接面向连接(先三次握手)无连接(直接发)
可靠性可靠(重传、确认)不可靠(丢了不管)
顺序保证有序不保证
速度相对慢快
开销大(包头 20 字节 + 握手)小(包头 8 字节)
适合要完整、要正确要快、能容忍少量丢失
典型网页、SSH、数据库DNS、直播、游戏、语音
>

一句话记忆:要准用 TCP,要快用 UDP。 日常你碰到的服务(网页、数据库、SSH)几乎全是 TCP。


5. NAT 与端口映射:为什么你家里设备都能上网

现在回到开头那个问题:你的笔记本是 192.168.1.2(内网 IP,不是公网门牌号),为什么能访问全世界?

答案是:NAT。

5.1 NAT 是什么

NAT(Network Address Translation,网络地址转换),翻译一下就是「把内网地址换成公网地址」。

你家里那台路由器,对着外网有一个真正的公网 IP(比如 203.0.113.7,运营商分配的),对着家里这一侧有一堆内网 IP(192.168.1.2、192.168.1.3……)。

路由器干的活:

家里设备(内网)                     互联网(公网)
192.168.1.2:54321
      │
      ▼
   ┌──────────────────────────────┐
   │   路由器(NAT)               │
   │  把源地址 192.168.1.2:54321   │
   │  改写成 203.0.113.7:54321     │
   │  并记一张「对照表」           │
   └──────────────────────────────┘
      │
      ▼
   203.0.113.7:54321  ──▶  服务器

关键点:

  • 出网时,路由器把数据包上「谁发的」(源地址)从内网 IP 改成自己的公网 IP。
  • 路由器同时记一张表:公网 203.0.113.7:54321 ←→ 内网 192.168.1.2:54321。
  • 服务器回数据时,发给 203.0.113.7:54321,路由器一查表,知道「哦,这其实是发给家里 192.168.1.2 的」,于是还原回去,转给笔记本。
>

类比:路由器就像公司的前台总机。外面打来的电话统一打到公司总机(公网 IP),前台查一下「54321 号线是找张三(192.168.1.2)」,再转接。你(内网设备)对外永远只露一个总机号码。

这就是为什么你家里几十台设备、全是 192.168.x.x,却只用一个公网 IP 就能一起上网——它们共享了同一个公网门牌号。

5.2 公网访问内网:要「端口映射」

上面的 NAT 解决了「内网主动访问外网」。但反过来——外网想主动访问你内网里的某台设备(比如你在家里的电脑上搭了个网站,想让别人从公网访问)——NAT 默认是不行的:路由器不知道「外面来的请求」该转给家里哪台机器。

这时需要手动配置端口映射 / 端口转发(Port Mapping / Port Forwarding):

>

在路由器上写一条规则:「外网打到我公网 IP 的 80 端口的请求,统统转给内网 192.168.1.2 的 80 端口。」

外网请求:  203.0.113.7:80
                │
                ▼
          ┌──────────────┐
          │ 路由器        │
          │ 端口映射规则:│
          │ :80 ─▶ 192.168.1.2:80 │
          └──────────────┘
                │
                ▼
        内网 192.168.1.2:80 (你家里那台跑网站的电脑)
>

类比:你在总机登记「80 号业务线的电话,一律转给 3 楼的网站部(192.168.1.2)」。

重要提醒:做端口映射前,先确认

  • 你家/公司的公网 IP 是固定的(很多家用宽带是动态的,重启就变,需要「公网固定 IP」或 DDNS 动态域名)。
  • 运营商没有封锁(有些宽带给的是「大内网」,公网 IP 其实也是个运营商网关,映射做不了)。
  • 映射之后,服务器自己的防火墙(第 6 节)也要放行那个端口,两层都得开。

6. 防火墙:门口的保安(ufw 实操)

防火墙(Firewall)是一道「保安墙」:它检查进出的每个数据包,按规则决定放行还是拦下。目的:防止不请自来的访问、控制谁能连你的哪些端口。

6.1 ufw 是什么

ufw 全称 Uncomplicated Firewall(「不复杂的防火墙」),是 Ubuntu/Debian 系系统自带的、最好用的防火墙前端。它其实是在管理底层的 iptables,但命令简单到小学生都能懂。

>

注意:ufw 默认是关闭的,而且默认规则是「拒绝入站、放行出站」。所以很多新手「服务起来了、端口也监听了,但外面连不上」——十有八九是防火墙没放行。

6.2 三个最常用的命令(照抄就能用)

# ① 放行 22 端口的 TCP 流量(允许别人 SSH 进来)
sudo ufw allow 22/tcp
#    输出:Rule added
#    输出:Rule added (v6)     ← 同时给 IPv6 也加了一条

# ② 启用防火墙(第一次需要 root 确认)
sudo ufw enable
#    输出:Firewall is active and enabled on system startup

# ③ 查看当前状态和已放行规则
sudo ufw status
#    输出:
#    Status: active
#
#    To                         Action      From
#    --                         ------      ----
#    22/tcp                     ALLOW       Anywhere
#    80/tcp                     ALLOW       Anywhere

再加几个你会用到的:

# 放行网页端口
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# 放行某个数据库端口(比如 MySQL)
sudo ufw allow 3306/tcp

# 看更详细的规则(含默认策略)
sudo ufw status verbose

# 删掉某条规则
sudo ufw delete allow 3306/tcp

# 临时关闭防火墙(排查时用,完事记得重新 enable!)
sudo ufw disable
>

安全提醒:

>
  • 数据库端口(3306/5432/6379)千万别对 Anywhere(全网)放行,正常只该给内网/指定 IP。真需要远程访问,用 sudo ufw allow from 1.2.3.4 to any port 3306 限定来源。
  • >
  • 改防火墙前先确保 SSH 是放行的(ufw allow 22),否则 ufw enable 之后你可能把自己远程锁在门外。

6.3 云厂商「安全组」是另一层

如果你在云服务器(阿里云/腾讯云/AWS 等)上,会发现:

>

「我在 ufw 里放行了 80,为什么外面还是连不上?」

因为云上不止一层墙:

层是什么在哪配
安全组(Security Group)云厂商在虚拟网络层的防火墙,相当于云上的「外网大门」云平台控制台 → 安全组
系统防火墙(ufw)操作系统内部的那道墙服务器里 ufw

两层都得放行,流量才进得来。 顺序是:

外网 ──▶ 安全组(云厂商) ──▶ ufw(系统) ──▶ 你的程序
         ↑ 第 1 道墙           ↑ 第 2 道墙
         两道都 allow,才通
>

排查口诀:云上连不上,先查安全组,再查 ufw,最后查程序有没有在监听那个端口。三层任何一层断了,都不通。


7. 常用网络排查命令(每个都配解释 + 输出)

下面 6 个命令,是网络排查的「六件兵器」。全部可直接复制。

7.1 ip addr —— 看「我是谁」(本机的 IP)

ip addr

作用:列出本机所有网络接口和它们的 IP 地址。排查第一步永远是「先确认我自己的 IP 是多少」。

典型输出(逐行解读):

1: lo: <LOOPBACK,UP,LOWER_UP> ...          ← lo 是「本地回环」接口,固定 127.0.0.1,
    inet 127.0.0.1/8 scope host lo          ←   专门给「本机访问自己」用,不是真实网卡
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> ← eth0 是你的真实网卡(可能是 wlan0/enp0s3 等)
    link/ether 52:54:00:12:34:56 ...        ←   上面是 MAC 地址(网卡物理号),一般不用管
    inet 192.168.1.2/24 brd 192.168.1.255 ... ← ★ 重点:你的内网 IP 192.168.1.2
                                                  /24 = 掩码 24 位(第 2 节),brd 是广播地址
    inet6 fe80::5054:.../64 ...             ← IPv6 本地地址(第 1.3 节),一般忽略

看什么:

  • 找到你那行 inet 192.168.x.x/24,那就是你的内网 IP。
  • lo 的 127.0.0.1 是回环,代表「本机」,跟外部网络无关。

7.2 ss -ltnp —— 看「谁在听」(本机监听了哪些端口)

ss -ltnp

参数逐个拆:

  • -l:只看 listening(正在监听) 的,不看已连接的
  • -t:只看 TCP(-u 是 UDP)
  • -n:不做域名解析,直接显示数字 IP:端口(更快更清晰)
  • -p:显示是哪个进程(程序)占用了这个端口(需要 root 才完整)

典型输出(逐列解读):

State      Recv-Q  Send-Q     Local Address:Port         Process
LISTEN     0       128        0.0.0.0:22                 users:(("sshd",pid=1234,fd=3))
LISTEN     0       128        127.0.0.1:3306             users:(("mysqld",pid=5678,fd=20))
LISTEN     0       511        0.0.0.0:8080               users:(("node",pid=910,fd=21))
LISTEN     0       128               [::]:443            users:(("nginx",pid=4321,fd=6))

看什么(重点):

  • Local Address:Port 列的 IP:端口 里,IP 是关键:
    • 0.0.0.0:8080 → 监听所有网卡的所有地址,外网能连(前提是防火墙放行)。
    • 127.0.0.1:3306 → 只监听本机回环,只有本机能访问,外网连不上!
    • [::]:443 → IPv6 通配地址,表示 IPv6 下监听所有地址(等价于 IPv4 的 0.0.0.0)。
  • Process 列告诉你是哪个程序(sshd=SSH、mysqld=MySQL、nginx=网页服务器)占用了它。
>

实战用法:

>
  • 「我起了个服务,为什么外面连不上?」→ 先 ss -ltnp 看它是不是监在 127.0.0.1(只对内),而不是 0.0.0.0。
  • >
  • 「8080 被谁占了?」→ 看 Process 列那个 pid,kill 掉 或改端口(第 9.1 节)。

7.3 ping —— 「对方在家吗?」(测可达性)

ping www.example.com
# 或者
ping 8.8.8.8

作用:用 ICMP 协议给对方发「在不在?」的探针,对方回「在」。能测网络通不通、延迟多少。注意:ping 通不代表服务通(很多防火墙会故意屏蔽 ping,但服务其实是好的)。

典型输出(逐行解读):

PING www.example.com (93.184.216.34) 56(84) bytes of data.
                              ↑ 域名被解析成了 IP 93.184.216.34
64 bytes from 93.184.216.34: icmp_seq=1 ttl=56 time=23.4 ms
                       ↑ 收到回包    ↑ 第几个包   ↑ ttl    ↑ 往返延迟(ms)
64 bytes from 93.184.216.34: icmp_seq=2 ttl=56 time=21.1 ms
64 bytes from 93.184.216.34: icmp_seq=3 ttl=56 time=22.8 ms
^C                          ← 按 Ctrl+C 手动停止
--- www.example.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
                              ↑ 发了3个,收到3个,丢包率0%(健康)
rtt min/avg/max/mdev = 21.100/22.433/23.400/1.020 ms
                              ↑ 延迟最小/平均/最大/波动

看什么:

  • 0% packet loss(0 丢包)+ 稳定延迟 → 网络通、质量好。
  • 100% packet loss(全丢)→ 要么对方没开、要么被防火墙挡了、要么网络断了。
  • 能 ping 通公网(8.8.8.8)但 ping 不通内网某台机器 → 多半是那台机器的防火墙屏蔽了 ICMP,或它其实关机了。
>

小技巧:ping -c 4 8.8.8.8 只发 4 个包就停(-c = count),适合脚本里用,不用手动 Ctrl+C。

7.4 curl -v —— 「我到底连上了没,连的什么」(看 HTTP 全过程)

curl -v https://www.example.com

参数:-v = verbose(啰嗦模式),把连接、TLS 握手、请求头、响应头全部打印出来。排查「网页打不开」的第一利器。

典型输出(逐段解读):

* Trying 93.184.216.34:443...
* Connected to www.example.com (93.184.216.34) port 443 (#0)
    ↑ 先连 IP:443,这一步成功 = 网络+端口是通的
* TLS connection using TLS 1.3 / AES_256_GCM
    ↑ TLS/HTTPS 握手成功 = 加密通道建好了
> GET / HTTP/1.1
> Host: www.example.com
> User-Agent: curl/8.0.1
> Accept: */*
>
    ↑ 以 > 开头的是「发给服务器的请求头」
< HTTP/1.1 200 OK
< Content-Type: text/html
< Server: nginx
<
    ↑ 以 < 开头的是「服务器返回的响应头」,200 = 成功
<html>...网页内容...</html>
* Connection #0 to host www.example.com left intact

看什么(排障核心):

  • 卡在 Trying ... 很久然后 Connection timed out → 网络/防火墙不通(见第 9.2)。
  • Connected 很快,但后面 Could not resolve 之类 → DNS 解析问题(见第 7.5)。
  • 连上了但 < HTTP/1.1 403/502/503 → 网络通了,是服务器应用层在报错(权限/后端挂了/过载)。
  • curl 通但浏览器不通 → 见第 11 节「常见坑」。

7.5 dig / nslookup —— 「域名对应哪个 IP」(查 DNS)

dig www.example.com          # 更详细、更强(推荐)
# 简版
dig +short www.example.com   # 只输出 IP,一行搞定
nslookup www.example.com     # 更老、更简单的替代品

作用:DNS 解析,把域名翻译成 IP。这是整条链的第一环——域名都解析不出来,后面全白搭。

典型输出:

$ dig +short www.example.com
93.184.216.34                ← 一行搞定:这个域名对应这个 IP

$ dig www.example.com        # 完整模式
; <<>> DiG 9.18.1 <<>> www.example.com
;; global options: +cmd
;; ANSWER:
www.example.com.    300    IN    A    93.184.216.34
    ↑ 域名          ↑TTL   ↑类型  ↑A记录=IPv4地址  ↑ 解析结果

看什么:

  • 有 ANSWER 段且有 A 记录 → 解析成功。
  • ;; status: NXDOMAIN → 域名不存在(拼错了 / 没注册 / DNS 服务器里没有)。
  • 解析出来的 IP 和「你以为的 IP」不一样 → 可能 DNS 被劫持、或 CDN 轮询(CDN 每次给不同 IP 是正常的)。
  • 能 curl 通 IP 但 curl 不通域名 → 多半是 DNS 解析的问题。

7.6 traceroute —— 「路是怎么走的,卡在哪一跳」(看路径)

traceroute 8.8.8.8
# 或用 TCP 443 端口(有些防火墙屏蔽了 traceroute 默认的 UDP,这时加 -T -p 443)
traceroute -T -p 443 www.example.com

作用:逐跳(逐台路由器)显示数据包从你到目标经过了哪些节点、每一跳延迟多少。用来定位「卡在哪一段」。

原理:它发送 TTL(生存时间)从 1 开始递增的包,TTL 每经过一台路由器减 1,减到 0 那台路由器就回一个「超时」,于是你就能看到「第 1 跳是谁、第 2 跳是谁……」。

典型输出(逐行解读):

traceroute to 8.8.8.8, 30 hops max, 60 byte packets
 1  192.168.1.1 (192.168.1.1)    1.23 ms  1.10 ms  1.05 ms   ← 第1跳:你家路由器
 2  203.0.113.1 (203.0.113.1)    8.45 ms  8.30 ms  8.22 ms   ← 第2跳:运营商入口
 3  198.51.100.23 (198.51.100.23) 12.3 ms ...               ← 第3跳:骨干网
 4  142.250.78.4 (142.250.78.4)  20.1 ms ...               ← ...
 ...
(中间的 * * * 表示该跳不回应,不一定是断,很多路由器会屏蔽)

看什么:

  • 从哪一跳开始延迟突然飙高或出现 * * *(不回应)→ 问题大概率出在那一跳或它之后的链路。
  • 如果第 1 跳(你家里/公司路由器)就 * * * → 你本地网络的问题。
  • 全程 * * * 到目标都到不了 → 目标不回应 traceroute(正常,换 curl -v/ping 再判断)。
>

注意:中间出现 * * * 不等于那跳挂了——很多运营商/防火墙故意不回 traceroute 探针。重点看「从哪一跳开始异常」。


8. 三大经典报错:到底在说什么、怎么查

排查网络,90% 你只会撞到下面这三种错误。看懂它们,你就超过了大部分人。

8.1 「端口被占用」 / Address already in use / EADDRINUSE

它说什么:你想让程序监听某个端口(比如 8080),但那个端口已经被人占了。同一台机器上,同一端口同一时间只能一个程序用。

怎么查 & 怎么解:

# 1. 看 8080 被哪个进程占了
ss -ltnp | grep 8080
# 假设输出:
# LISTEN  0  511  0.0.0.0:8080  users:(("node",pid=910,fd=21))
#                          ↑ 端口8080   ↑ 是 node 进程,pid=910

# 2. 确认那个进程确实可以杀
ps -p 910          # 看一下 pid 910 到底是个啥,别杀错

# 3. 杀它(二选一)
kill 910           # 温和地请求它退出
kill -9 910        # 强制杀死(上招没用再上这招)

# 4. 或者,干脆换个端口启动你的服务
PORT=8081 ./start.sh    # 很多服务支持用环境变量/参数换端口
>

避坑:

>
  • 别上来就 kill -9,先 ps 确认不是系统关键进程。
  • >
  • 有些端口(如 80、22)必须 root 才能监听(01023 是特权端口),普通用户起服务会「权限不足」,换 8080 这种 >1024 的端口,或用 sudo。

8.2 「连接超时」 / Connection timed out / timed out

它说什么:数据包发出去了,等了很久没有任何回应,最后超时放弃。关键词是「没回应」——注意,它不等于「对方明确拒绝」。

它通常意味着:

  • 中间的防火墙/安全组把包静默丢掉了(最常见!丢包不回任何消息)。
  • IP 地址写错了 / 目标其实不在那个网段。
  • 网络本身不通(没连上 / 断网)。
  • 目标过载,根本没空理你。

怎么查(按顺序):

# 1. 先确认基础网络通不通(能不能上网)
ping -c 3 8.8.8.8

# 2. 看路径卡在哪一跳
traceroute -T -p 443 www.example.com

# 3. 用 curl -v 看是不是卡在「连 IP:端口」这一步
curl -v https://www.example.com
#    卡在 "Trying ...:443..." → 就是这一层的问题

# 4. 云上?先查【安全组】放行了没,再查 ufw
sudo ufw status
>

对比记忆:

>
  • 超时(timeout) = 没人理你(被静默丢包 / 网络不通)→ 先查防火墙/安全组/网络。
  • >
  • 拒绝(refused,下面那个) = 有人理你,但说「不」→ 先查服务有没有起、监听地址对不对。
> >

一句话:「超时」往「墙和网络」上找,「拒绝」往「程序」上找。

8.3 「拒绝连接」 / Connection refused / ECONNREFUSED

它说什么:网络是通的、包也到了那台机器,但机器上明确回了个「拒绝」(TCP RST)。关键词是「有人回话,但说没有」。

它通常意味着:

  • 目标机器上,那个端口根本没有程序在监听(服务没起 / 崩了 / 还没起来)。
  • 服务起来了,但监听地址不对(比如监在 127.0.0.1,而你从外网连,127.0.0.1 只对那台机器自己有效)。
  • 端口号写错了。

怎么查:

# 在【目标机器】上执行:看那个端口到底有没有人在听
ss -ltnp | grep 3306
# 情况A:啥都没有 → 服务没起来。把服务启动起来:
#     systemctl start mysql      (以 MySQL 为例)
# 情况B:监在 127.0.0.1:3306 → 只对内。改配置让它监听 0.0.0.0:
#     (MySQL: 改 my.cnf 的 bind-address;或临时用 -bind-address)
#     (很多服务: --host 0.0.0.0 或 PORT 环境变量)
# 情况C:监在 0.0.0.0:3306 → 端口是开的,那问题可能在【你这一端或防火墙】,
#     回到 8.2 的超时排查思路。

# 用 curl 验证(在【你这一端】)
curl -v telnet://目标IP:3306
#    连上了(出现 Connected)→ 说明端口是通的,之前 refused 是服务/地址问题
#    还是 refused → 确认目标机器上端口没监听
>

快速判断口诀:
>

报错一句话往哪找
timed out(超时)没人理我防火墙 / 安全组 / 网络
refused(拒绝)人到了,说没这个服务服务没起 / 监听地址 / 端口号

9. 一张图讲清:浏览器访问网站的完整数据流

把前面所有概念串起来,你在浏览器里输入 https://www.example.com 回车后,到底发生了什么:

你按下回车
    │
    ▼
① DNS 解析(dig / 系统自动做)
   www.example.com  ──▶  93.184.216.34     ←「域名翻译成 IP(门牌号)」
    │
    ▼
② 你的电脑发起 TCP 连接(三次握手)
   源:本机内网 192.168.1.2:54321   (54321 是你电脑临时随机挑的源端口)
   目的:93.184.216.34:443          (443 = HTTPS 的房间号)
    │
    ▼
③ 经过家里路由器(NAT + 本机防火墙)
   · 路由器把【源地址】从 192.168.1.2:54321
     改写成【公网地址】203.0.113.7:54321
   · 并记一张对照表:203.0.113.7:54321 ←→ 192.168.1.2:54321
   · 出方向通常放行(ufw 默认出站全开)
    │
    ▼
④ 数据包穿越运营商骨干网(traceroute 能看到的每一跳)
    │
    ▼
⑤ 到达服务器:先过【云安全组】,再过【系统防火墙 ufw】
   · 安全组:443 放行了吗?
   · ufw:443 放行了吗?
   · 两层都 allow,包才能进去
    │
    ▼
⑥ 服务器上的程序接管:443 端口由 Nginx 监听
   · 完成 TLS 加密握手(https 的「s」)
   · 解析你的请求(GET /),处理,生成响应
    │
    ▼
⑦ 响应沿【原路】返回
   · 服务器防火墙放行出站
   · 路由器查对照表:203.0.113.7:54321 → 还原成 192.168.1.2:54321
   · 你电脑收到 200 OK + 网页内容
    │
    ▼
浏览器渲染出网页 ✅

每个概念在图里的位置:

概念在哪一步出现
IP(门牌号)① 解析出 93.184.216.34;③ 源被改成 203.0.113.7
端口(房间号)② 目的 443、源 54321;⑥ 由 443 的 Nginx 接管
TCP② 三次握手建立可靠连接
NAT③ 内网↔公网地址互转
防火墙③ 路由器那侧;⑤ 安全组 + ufw 两层
DNS① 域名 → IP
>

看懂这张图,你就把「IP、端口、协议、NAT、防火墙」全部串成一条线了——它们不是五个孤立的东西,而是同一次访问里,先后被用到的五件套。


10. 常见坑与避坑表

#坑现象原因怎么避 / 怎么解
1端口没放行服务在跑、端口在监听,外网连不上防火墙/安全组没 allow 那个端口云上先查安全组,再 sudo ufw allow 80/tcp;改完 ufw status 确认
2内外网 IP 搞混用 192.168.1.2 去外网连,连不上内网 IP 只对局域网有效,外网不认对外用公网 IP(或域名);对内才用 192.168.x.x
3服务只监听 127.0.0.1本机 curl 127.0.0.1:8080 通,外网 curl 服务器IP:8080 拒绝监听地址是回环,只对本机有效改配置监听 0.0.0.0(ss -ltnp 确认 Local Address 列)
4curl 通但浏览器不通curl http://IP 能拿到 200,浏览器打不开浏览器走的是域名+443+证书+缓存,curl 走的是你指定的 IP/80用 curl -v https://域名 复现;查 DNS、证书、代理;浏览器清缓存/无痕
5NAT 回环(Hairpin)在外网能访问 公网IP:80,在家里局域网却访问不了同一个 公网IP:80路由器不支持「内网访问自己公网 IP」的回环局域网内改用内网 IP或局域网域名访问;或让路由器支持 NAT Loopback
6端口被占用启动服务报 Address already in use端口已被别的进程监听ss -ltnp 找 pid → kill,或换端口(>1024)
7特权端口需 root普通用户起 80/443 报权限错误01023 是特权端口换 8080/8443,或 sudo,或用 setcap 给程序加权限
8能 ping 通 ≠ 服务通ping 正常,但网页/服务连不上防火墙常只屏蔽 ICMP,服务端口是另一码事别只看 ping,用 curl -v/ss 直接测端口
9动态公网 IP 变来变去昨天能访问,今天 公网IP:80 打不开家用宽带公网 IP 是动态的,重启就变用 DDNS 动态域名,或申请固定公网 IP
10两层墙只开了一层ufw 放行了,云上还是连不上安全组和 ufw 是两道独立的墙两层都放行:先安全组,后 ufw
11数据库端口全网开放MySQL/Redis 对 Anywhere 放行安全大忌,容易被扫/被攻击只放行给指定 IP:sudo ufw allow from 1.2.3.4 to any port 3306
12忘了给自己留后路ufw enable 后 SSH 被锁在外面启用前没放行 22启用前先 sudo ufw allow 22/tcp,再 ufw enable

11. 最后:把术语一次性钉牢(速记卡)

术语一句话类比
IP设备的门牌号(192.168.1.2)楼号
公网/内网 IP公网全球唯一;内网只在局域网有效门牌 vs 房间内部号
子网掩码/CIDR划出「哪几位是小区号」,/24=254 个房间小区号长度
网关小区通外网的大门(路由器)小区保安亭
端口机器上程序的房间号(065535)楼里的分机号
TCP可靠、有序、慢(握手+重传)慢递
UDP快、不可靠(不握手)快递
NAT路由器把内网 IP 换公网 IP(共享上网)公司总机
端口映射外网端口 → 内网某设备某端口总机登记转接
防火墙/安全组按规则放行/拦截流量门口保安
DNS域名 ↔ IP 的翻译查号台
ping测通不通 + 延迟「在不在?」
ss看本机谁在监听哪个端口查分机表
curl -v看连接+握手+请求响应全过程看通话录音
dig域名翻译成 IP查号
traceroute看数据经过的每一跳看快递轨迹
>

排障总口诀(记这一句就够):
> 先 ping/curl -v 判断「通不通」,再 ss -ltnp 看「服务在不在、监听对不对」,最后查「防火墙/安全组放没放行」。
> 超时 → 找墙和网络;拒绝 → 找程序和端口。

(完)

— 感谢阅读 —

一起交流

分享你的思考,让讨论更进一步。