在Client A和Client B之间建立UDP直连的过程如下:
(1) Client A登录Server S,NAT A 为这次的Section分配了一个端口55000,那么Server S收到Client A的地址是100.10.10.10:55000,这就是Client A的外网地址。
(2)Client B登录 Server S, NAT B 给此次Section分配的端口是44000,那么Server S收到B的地址是:200.20.20.20:44000。
此时,Client A 与Client B 都可以与Server S通信了。如果此时Client A想直接发送UDP数据包给Client B,那么 Client A可以从Server S 中获得B的公网地址:200.20.20.20:44000,但是Client A还不能使用该公网地址直接和Client B通信,因为此时NAT B会将Client A主动发来的信息丢弃,因为此数据包是没有会话记录的。
(3)现在需要在NAT B上打一个方向为100.10.10.10:55000(即Client A的外网地址)的洞,那么Client A发送到200.20.20.20:44000的信息,Client B就能收到了。
(4)Server S负责向Client B发送打洞指令。
(5)Client B向Client A的公网地址发送一个UDP报文,虽然此时数据包会被NAT A丢弃,但是在NAT B上建立了会话记录,不会丢弃Client A的包了。
(6)Server S通知Client A "洞"已打好,Client A可以发数据包给Client B了。
(7)Client A向Client B发送UDP包。
(8) 至此双方可以进行UDP通信了。
注意:
以上过程仅适合Cone NAT的情况,如果是对称的NAT,那么当Client B向Client A发送报文时,Client A的打洞端口已经从新分配了,Client B将无法得知,这个时候可以用一个端口猜测算法(该算法不适用全部,但大部分适用)。