首先判斷是否可以直連,可以直連,表明內網環境,直接通訊。否則需要一箇中間人的角色:Server。所以打洞的過程如圖所示:
主要流程是這樣的:
(1)如果A想與B通信;
(2)A首先連接C,C得到A的外網NAT A的地址和端口;
(3)B也要連接C,C得到B的外網NAT B的地址和端口;
(4)A告訴C說我要和B通訊;
(5)C通過NAT B發信息給B,告訴B A的外網NAT A的地址和端口;
(6)B向NAT A發數據包(肯定會被NAT A丟棄,因爲NAT A上並沒有 A->NAT B 的合法session),但是NAT B上就建立了有B->NAT A的合法session了;
(7)B發數據包給C,讓 C 通知 A,我已經把洞打好了;
(8)A接受到通知後向 B 的外網發NB數據包,這樣就不會被丟棄掉了。因爲對於NAT B來說,它看到的是A的外網NAT A的地址,而通過第6步,B已經讓NAT A成爲NAT B的合法通信對象了。所以當NAT A發數據包給NAT B時,NAT B就會接收並轉發給B;
說明:只適應某些路由。
代碼地址:
https://gitee.com/lgcjava/p2pnats.git
聯繫方式:
QQ:153277817