一、为什么需要NAT穿透?
先问大家一个问题:两台电脑都在各自的公司内网里,它们能直接建立连接吗?
答案往往是不能。原因很简单——IPv4地址不够用了。
全球IPv4地址总数约43亿个,听起来不少,但全球联网设备早就超过这个数了。于是NAT(网络地址转换)技术应运而生。它让一个公网IP可以给成百上千的内网设备共享使用。
我刚开始做WebRTC时,就踩过这个坑。本地测试一切正常,一部署到客户现场就炸了。后来才发现,客户的网络环境是典型的NAT场景,而我的代码根本没考虑穿透问题。
NAT的工作原理
NAT设备(通常是路由器)维护一张映射表。当内网设备访问外网时,NAT会分配一个公网端口,把内网IP:端口映射到公网IP:端口。
举个例子:
内网设备:192.168.1.100:12345
→ NAT映射后:203.0.113.5:65000
→ 访问目标:8.8.8.8:80
外网服务器看到的是203.0.113.5:65000,而不是真正的内网地址。这就是NAT的"障眼法"。
核心问题:两个内网设备想直接通信,但彼此都不知道对方的真实内网地址,只知道对方经过NAT映射后的公网地址。而这个映射关系,又不是固定不变的。
二、对称NAT的穿透难点
NAT有四种类型,其中对称NAT是最难对付的。我个人习惯把NAT类型分成两类:好对付的和不好对付的。对称NAT就属于后者。
NAT的四种类型
| NAT类型 | 端口映射行为 | 穿透难度 |
|---|---|---|
| 完全锥形NAT | 所有外部主机都能通过映射的端口访问 | 容易 |
| 受限锥形NAT | 只有内网设备曾访问过的外部主机能访问 | 中等 |
| 端口受限锥形NAT | 限制更严格,要求外部主机的IP和端口都匹配 | 较难 |
| 对称NAT | 每次连接都分配不同的端口映射 | 极难 |
对称NAT为什么难穿透?
对称NAT的"狡猾"之处在于:它每次建立新连接,都会分配一个不同的公网端口。
你想想看:
- 设备A通过NAT-A访问服务器S,获得映射端口10001
- 设备B通过NAT-B访问服务器S,获得映射端口20001
- 服务器告诉A:B的公网地址是X.X.X.X:20001
- 服务器告诉B:A的公网地址是Y.Y.Y.Y:10001
- A尝试连接B的20001端口——但NAT-B只允许来自S的连接通过
- A的这次新连接,NAT-A又分配了一个新端口10002
这就陷入死循环了。我在项目中遇到过这种情况,当时调试了整整两天才定位到问题。客户用的是某运营商的4G网络,恰好是对称NAT,导致视频通话始终建立不起来。
避坑指南:我曾经以为TURN服务器能解决所有问题,但对称NAT环境下,即使有TURN,如果配置不当,仍然可能失败。关键是要确保TURN服务器使用正确的传输协议(TCP或TLS)。
三、传统P2P通信的困境
传统的客户端-服务器模式,通信很简单:客户端连服务器,服务器转发数据。但P2P不一样,它想让两个客户端直接对话。
困境在哪?说白了就三点:
困境一:地址不可达
内网设备没有公网IP,外网设备无法主动连接它。即使知道它的公网映射地址,这个映射也可能随时失效。
困境二:映射不可预测
对称NAT的端口映射是随机的。你无法预测下一次连接会分配到哪个端口。这就好比两个人约见面,但每次见面地点都随机变化,而且双方都不知道对方的新地点。
困境三:防火墙拦截
很多企业网络有严格的防火墙策略。即使NAT穿透成功了,防火墙也可能把P2P流量当作攻击行为直接拦截。
我记得有个金融客户,他们的网络策略是只允许80和443端口通过。我们不得不把所有WebRTC流量伪装成HTTPS流量,才勉强跑通。
我的建议:做P2P通信开发,一定要提前了解目标网络的NAT类型。如果超过30%的用户是对称NAT,那就老老实实部署TURN服务器吧,别在穿透上死磕。
四、NAT穿透的核心逻辑
说了这么多问题,那NAT穿透到底是怎么实现的?我画了一张图,帮你理清思路。
流程其实不复杂:
- 设备A通过信令服务器告诉设备B自己的地址
- 设备B也通过信令服务器告诉设备A自己的地址
- 双方尝试直接连接对方
- 如果NAT类型友好,连接成功
- 如果遇到对称NAT,连接失败,需要TURN中继
嗯,这里要注意:信令服务器只负责交换地址信息,不传输媒体数据。这是WebRTC设计上的一个精妙之处——控制面和数据面分离。
总结一下:NAT穿透的本质,就是想办法让两个内网设备"猜"到对方的真实映射地址,并在映射失效前完成连接。对称NAT之所以难,是因为它让这个"猜测"变得几乎不可能。
我在实际项目中,遇到过最极端的情况:两个设备都在对称NAT后面,而且NAT的端口分配策略是每30秒变化一次。这种情况下,别说P2P穿透了,连维持连接都困难。最后只能走TURN中继,虽然延迟高了一些,但至少能通。
所以,做WebRTC开发,一定要有"穿透失败"的心理准备。不要把所有希望都寄托在P2P上,该上TURN就上TURN。毕竟,用户只关心视频能不能打通,才不管你是P2P还是中继。
公众号:蓝海资料掘金营,微信deep3321