两个 NAT3 设备如何进行 P2P 通信
NAT3 的规矩是:设备A访问过设备B的IP:端口后,只有B用那个精确的IP:端口发回的数据才能进来。不仅IP要对,端口也必须一模一样。
假设:
设备A:公网地址 203.0.113.1:55000
设备B:公网地址 198.51.100.2:65000
要求双方必须使用完全相同的端口进行通信,否则NAT不让过。
第一步:交换地址(必须精确到端口)
通过服务器S协调:
A告诉S:我的公网地址是 203.0.113.1:55000
B告诉S:我的公网地址是 198.51.100.2:65000
S告诉A:B的地址是 198.51.100.2:65000
S告诉B:A的地址是 203.0.113.1:55000
注意:这里交换的必须是对方连接服务器时使用的精确公网端口。
第二步:发送数据包,但是有个关键问题——映射端口会变吗?
这才是难点!当A从连接服务器改为连接B时,它的NAT可能会:
情况1:复用同一个公网端口55000
情况2:分配一个全新的端口55001
如果端口变了,游戏结束。怎么确保端口不变呢?
方法1:利用NAT的端口分配规律
有些NAT设备有 "端口一致性":只要内网设备用相同的内部端口,无论连接谁,NAT都给分配相同的公网端口。
比如:
A用内网端口5000连服务器S → NAT给公网端口55000
A用内网端口5000连设备B → NAT还给55000
但这不是100%保证,要看具体NAT设备。
方法2:根据端口顺序进行猜测,多端口同时试,谁先通就用谁
A向B的多个端口发送:65000、65001、65002...
B向A的多个端口发送:55000、55001、55002...
A和B都是NAT3,想视频通话,完整流程:
第1步:各自找STUN服务器
A → STUN:我长啥样?
STUN → A:你公网是203.0.113.1:55000
B → STUN:我长啥样?
STUN → B:你公网是198.51.100.2:65000
第2步:通过信令服务器交换地址
A → 服务器S:我的地址是203.0.113.1:55000
B → 服务器S:我的地址是198.51.100.2:65000
S → A:B在198.51.100.2:65000
S → B:A在203.0.113.1:55000
第3步:协调打洞时间
S → A和B:2秒后开始打洞,用我告诉你们的精确地址
第4步:打洞
A → B:数据发往198.51.100.2:65000
B → A:数据发往203.0.113.1:55000
如果双方NAT都复用端口:
- B的数据到达A的NAT,检查:来源是198.51.100.2:65000
A之前向198.51.100.2:65000发过数据 → 允许通过
- A的数据到达B的NAT,同理通过
第5步:连接确认
A收到B的数据,回复确认
B收到A的数据,回复确认
双向连接建立,可以开始通信啦!