首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >联机使用的内网穿透、P2P 的网络原理,你真的理解了吗?(上)

联机使用的内网穿透、P2P 的网络原理,你真的理解了吗?(上)

作者头像
海棠未眠
发布2025-10-22 16:42:21
发布2025-10-22 16:42:21
2600
代码可运行
举报
运行总次数:0
代码可运行

一、前言:朋友进不来房间的那一刻

你可能也遇到过这样的情况:

“我在《饥荒:联机版》里开了房,怎么别人就是进不来?” “为什么我在《泰拉瑞亚》里开局,朋友连不上?” “明明我们都在一个 Wi-Fi,下个 Hamachi 就能连,为什么?”

很多人第一次接触“内网穿透”这个词,都是从这种痛苦的联机经历开始的。 那种感觉就像——“我好不容易建了个世界,朋友却永远停在加载界面。”

一开始我们以为是游戏卡顿、网络延迟、服务器炸了, 后来才知道——不是网不好,而是网络结构不允许你们直接连接。

从那一刻开始,你才会真正意识到: 所谓的“网络连接”,并不是简单地在两台电脑之间传输数据。 中间隔着运营商的 NAT、防火墙、不同网段、不同出口, 有时候,数据包根本到不了你的电脑。

而“内网穿透”、“P2P”、“VPN”这些词, 就是为了解决“让两台机器在复杂网络下互相找到彼此”而存在的技术。

本文,我们就从游戏联机的角度出发,一步步拆开这些概念的真实含义。 我们不讲空洞的理论,而从你玩游戏的“那一秒钟开始”,去理解网络背后的逻辑。


二、网络连接的本质:一切都要“能找到彼此”

在讨论任何网络技术之前,我们必须问自己一个最简单的问题:

当你连接到一个服务器时,电脑究竟做了什么?

从 TCP/IP 的角度看,所有通信都是建立在IP 地址 + 端口号的组合上。 IP 地址用来定位设备,端口号用来区分进程。

一个完整的连接可以用四元组表示:

代码语言:javascript
代码运行次数:0
运行
复制
<源IP, 源端口, 目的IP, 目的端口>

只要这四个信息被唯一确定,操作系统的 TCP 协议栈就能建立一条连接。

例如,你访问一个 Minecraft 服务器:

代码语言:javascript
代码运行次数:0
运行
复制
客户端:192.168.1.101:54321
服务端:47.92.16.88:25565

这条连接能顺利建立,是因为客户端知道服务端的公网 IP, 而且服务端的 25565 端口在监听,没有被阻断。

但如果两台电脑都在 NAT(内网)后面呢? ——你根本拿不到对方的真实公网 IP,数据包自然发不到目标上。

这,就是“联机失败”的根源。 很多人以为是“游戏服务器问题”,其实根本原因是:

你和朋友根本不在同一个可寻址的网络空间里


三、NAT 与内网:互联网的“防火墙”与“翻译官”

1. NAT 是什么?

NAT(Network Address Translation,网络地址转换) 是现代互联网最普遍、最无处不在的机制。

它的作用简单来说就是:让一堆内网设备,共享一个公网 IP 上网。

假设你家路由器的公网地址是 120.245.10.23, 你电脑的局域网地址是 192.168.1.101。 当你访问百度时,请求实际上是这样被改写的:

代码语言:javascript
代码运行次数:0
运行
复制
源地址:192.168.1.101:54321  →  120.245.10.23:60123
目的地址:220.181.38.150:80

NAT 把你内网的源地址改成了公网地址,并做了一份映射表:

代码语言:javascript
代码运行次数:0
运行
复制
内网主机端口 54321 → 公网端口 60123

等百度返回响应包时,NAT 再把公网地址翻译回内网的地址。 整个过程对你是透明的。

这听起来很高效,也确实解决了“IPv4 地址不够”的问题。 但问题在于:NAT 是单向的。


2. NAT 的致命问题:外部无法主动连接

当你主动访问别人时,NAT 可以为你分配一个映射; 但当别人想“主动访问你”时,没有这份映射,就无路可走。

举个例子:

你在家开了 Minecraft 服务器,IP 是 192.168.1.101:25565。 你的公网地址是 120.245.10.23,但这只是你路由器的 IP。 当朋友尝试连接 120.245.10.23:25565 时,请求打到了你的路由器, 但路由器并不知道该把数据包转发给哪台内网主机——于是直接丢弃。

这就是为什么你开了服务器,别人进不来的原因。 因为在公网层面上,你这台主机是“隐形的”。

3. 为什么游戏厂商要自己建服务器

这也解释了为什么像《英雄联盟》、《CS2》、《原神》这类游戏, 都不会让你自己开房,而是统一通过官方服务器中转

官方服务器有固定的公网 IP,所有客户端都能主动连接。 玩家之间的数据交互由服务器协调, 虽然有额外延迟,但保证了“可达性”。

换句话说,官方服务器其实就是“反内网穿透”服务。 它让每一个 NAT 背后的玩家,都能通过一个共同的公网桥梁进行通信。


四、内网穿透:穿越 NAT 的“魔法通道”

游戏开发者显然不可能给每个玩家都配一个公网 IP。 于是,“内网穿透”技术诞生了。

它的核心目标就是一句话:

让一台处于内网、没有公网 IP 的设备,也能被外部主动访问。


1. 最原始的做法:端口映射与 DMZ

如果你能登录路由器,就能手动配置端口映射(Port Forwarding)。

例:

代码语言:javascript
代码运行次数:0
运行
复制
外部端口 25565 → 内部主机 192.168.1.101:25565

这样,外部访问 120.245.10.23:25565 时,路由器就会自动转发到你电脑。 这就是最简单的“内网穿透”。

DMZ(Demilitarized Zone)功能则更暴力,它把所有流量都转发给某台内网主机。 虽然方便,但安全性极低。

但在很多场景下(例如多人局域网游戏),你并不一定能控制路由器。 宿舍、办公室、校园网,往往连管理权限都没有。 于是就需要更聪明的办法。


2. 反向代理:让“外部主动连接你”变成“你主动连接外部”

反向代理的核心思想是:由内网主机主动建立连接到外部服务器,保持通道不断开。

例如: 你在本地启动了一个程序,它连接到云服务器 A。 当外部玩家想访问你时,请求打到服务器 A, A 再通过已有的通道把流量转发回你电脑。

这其实就是像 ngrok、frp、花生壳 的工作方式。

伪代码理解:

代码语言:javascript
代码运行次数:0
运行
复制
# 内网主机 -> 外网服务器
client.connect(server)
# server 注册映射关系
server.map(public_port=25565, client_socket)
# 外部访问时
server.on_request(public_port) -> forward_to(client_socket)

所有穿透行为都由“云端中继”完成。 代价是多了一跳转发,延迟和带宽受限于中继服务器。


3. 自动化的奇迹:NAT 打洞(Hole Punching)

真正的“P2P 穿透”是靠 NAT 打洞(Hole Punching) 实现的。 它的原理看起来复杂,其实很优雅:

  1. 双方都先向一个中间服务器(称为“协调服务器”)发送一个UDP包;
  2. 协调服务器记录下每一方的外网映射端口
  3. 然后告诉双方:“对方的外网地址是 xxx”;
  4. 双方同时对对方的地址发送UDP包;
  5. NAT 设备看到“这两个地址都有出站请求”,就会允许对应的入站响应通过。

这样,即使两台电脑都在 NAT 背后,也能直接建立通信。

这就是Steam、Epic、腾讯会议、WebRTC等系统中普遍使用的技术。


4. 为什么有时候打不通?

因为 NAT 有多种类型,打洞成功率并非 100%。

NAT 类型

特点

是否支持打洞

Full Cone

映射端口固定,最宽松

✅ 高

Restricted Cone

限制目标 IP

✅ 中

Port Restricted

限制目标 IP + 端口

⚠️ 一般

Symmetric NAT

每个连接动态映射

❌ 几乎不行

在家庭宽带中,一般是前两种; 但在校园网、公司网、移动热点中,多为 Symmetric NAT,这就是为什么“打不通”的根源。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-10-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、前言:朋友进不来房间的那一刻
  • 二、网络连接的本质:一切都要“能找到彼此”
  • 三、NAT 与内网:互联网的“防火墙”与“翻译官”
    • 1. NAT 是什么?
    • 2. NAT 的致命问题:外部无法主动连接
    • 3. 为什么游戏厂商要自己建服务器
  • 四、内网穿透:穿越 NAT 的“魔法通道”
    • 1. 最原始的做法:端口映射与 DMZ
    • 2. 反向代理:让“外部主动连接你”变成“你主动连接外部”
    • 3. 自动化的奇迹:NAT 打洞(Hole Punching)
    • 4. 为什么有时候打不通?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档