你可能也遇到过这样的情况:
“我在《饥荒:联机版》里开了房,怎么别人就是进不来?” “为什么我在《泰拉瑞亚》里开局,朋友连不上?” “明明我们都在一个 Wi-Fi,下个 Hamachi 就能连,为什么?”
很多人第一次接触“内网穿透”这个词,都是从这种痛苦的联机经历开始的。 那种感觉就像——“我好不容易建了个世界,朋友却永远停在加载界面。”
一开始我们以为是游戏卡顿、网络延迟、服务器炸了, 后来才知道——不是网不好,而是网络结构不允许你们直接连接。
从那一刻开始,你才会真正意识到: 所谓的“网络连接”,并不是简单地在两台电脑之间传输数据。 中间隔着运营商的 NAT、防火墙、不同网段、不同出口, 有时候,数据包根本到不了你的电脑。
而“内网穿透”、“P2P”、“VPN”这些词, 就是为了解决“让两台机器在复杂网络下互相找到彼此”而存在的技术。
本文,我们就从游戏联机的角度出发,一步步拆开这些概念的真实含义。 我们不讲空洞的理论,而从你玩游戏的“那一秒钟开始”,去理解网络背后的逻辑。
在讨论任何网络技术之前,我们必须问自己一个最简单的问题:
当你连接到一个服务器时,电脑究竟做了什么?
从 TCP/IP 的角度看,所有通信都是建立在IP 地址 + 端口号的组合上。 IP 地址用来定位设备,端口号用来区分进程。
一个完整的连接可以用四元组表示:
<源IP, 源端口, 目的IP, 目的端口>
只要这四个信息被唯一确定,操作系统的 TCP 协议栈就能建立一条连接。
例如,你访问一个 Minecraft 服务器:
客户端:192.168.1.101:54321
服务端:47.92.16.88:25565
这条连接能顺利建立,是因为客户端知道服务端的公网 IP, 而且服务端的 25565 端口在监听,没有被阻断。
但如果两台电脑都在 NAT(内网)后面呢? ——你根本拿不到对方的真实公网 IP,数据包自然发不到目标上。
这,就是“联机失败”的根源。 很多人以为是“游戏服务器问题”,其实根本原因是:
你和朋友根本不在同一个可寻址的网络空间里。
NAT(Network Address Translation,网络地址转换) 是现代互联网最普遍、最无处不在的机制。
它的作用简单来说就是:让一堆内网设备,共享一个公网 IP 上网。
假设你家路由器的公网地址是 120.245.10.23
,
你电脑的局域网地址是 192.168.1.101
。
当你访问百度时,请求实际上是这样被改写的:
源地址:192.168.1.101:54321 → 120.245.10.23:60123
目的地址:220.181.38.150:80
NAT 把你内网的源地址改成了公网地址,并做了一份映射表:
内网主机端口 54321 → 公网端口 60123
等百度返回响应包时,NAT 再把公网地址翻译回内网的地址。 整个过程对你是透明的。
这听起来很高效,也确实解决了“IPv4 地址不够”的问题。 但问题在于:NAT 是单向的。
当你主动访问别人时,NAT 可以为你分配一个映射; 但当别人想“主动访问你”时,没有这份映射,就无路可走。
举个例子:
你在家开了 Minecraft 服务器,IP 是 192.168.1.101:25565。 你的公网地址是 120.245.10.23,但这只是你路由器的 IP。 当朋友尝试连接 120.245.10.23:25565 时,请求打到了你的路由器, 但路由器并不知道该把数据包转发给哪台内网主机——于是直接丢弃。
这就是为什么你开了服务器,别人进不来的原因。 因为在公网层面上,你这台主机是“隐形的”。
这也解释了为什么像《英雄联盟》、《CS2》、《原神》这类游戏, 都不会让你自己开房,而是统一通过官方服务器中转。
官方服务器有固定的公网 IP,所有客户端都能主动连接。 玩家之间的数据交互由服务器协调, 虽然有额外延迟,但保证了“可达性”。
换句话说,官方服务器其实就是“反内网穿透”服务。 它让每一个 NAT 背后的玩家,都能通过一个共同的公网桥梁进行通信。
游戏开发者显然不可能给每个玩家都配一个公网 IP。 于是,“内网穿透”技术诞生了。
它的核心目标就是一句话:
让一台处于内网、没有公网 IP 的设备,也能被外部主动访问。
如果你能登录路由器,就能手动配置端口映射(Port Forwarding)。
例:
外部端口 25565 → 内部主机 192.168.1.101:25565
这样,外部访问 120.245.10.23:25565
时,路由器就会自动转发到你电脑。
这就是最简单的“内网穿透”。
DMZ(Demilitarized Zone)功能则更暴力,它把所有流量都转发给某台内网主机。 虽然方便,但安全性极低。
但在很多场景下(例如多人局域网游戏),你并不一定能控制路由器。 宿舍、办公室、校园网,往往连管理权限都没有。 于是就需要更聪明的办法。
反向代理的核心思想是:由内网主机主动建立连接到外部服务器,保持通道不断开。
例如: 你在本地启动了一个程序,它连接到云服务器 A。 当外部玩家想访问你时,请求打到服务器 A, A 再通过已有的通道把流量转发回你电脑。
这其实就是像 ngrok、frp、花生壳 的工作方式。
伪代码理解:
# 内网主机 -> 外网服务器
client.connect(server)
# server 注册映射关系
server.map(public_port=25565, client_socket)
# 外部访问时
server.on_request(public_port) -> forward_to(client_socket)
所有穿透行为都由“云端中继”完成。 代价是多了一跳转发,延迟和带宽受限于中继服务器。
真正的“P2P 穿透”是靠 NAT 打洞(Hole Punching) 实现的。 它的原理看起来复杂,其实很优雅:
这样,即使两台电脑都在 NAT 背后,也能直接建立通信。
这就是Steam、Epic、腾讯会议、WebRTC等系统中普遍使用的技术。
因为 NAT 有多种类型,打洞成功率并非 100%。
NAT 类型 | 特点 | 是否支持打洞 |
---|---|---|
Full Cone | 映射端口固定,最宽松 | ✅ 高 |
Restricted Cone | 限制目标 IP | ✅ 中 |
Port Restricted | 限制目标 IP + 端口 | ⚠️ 一般 |
Symmetric NAT | 每个连接动态映射 | ❌ 几乎不行 |
在家庭宽带中,一般是前两种; 但在校园网、公司网、移动热点中,多为 Symmetric NAT,这就是为什么“打不通”的根源。