這時可能會有兩種情況發生,一種是NAT再次新增一個Session,並且再次為這個Session分配一個連接阜號(比如:62001)。
另外一種是NAT再次新增一個Session,但是不會新分配一個連接阜號,而是用原來分配的連接阜號62000。前一種NAT叫做Symmetric NAT,後一種叫做Cone NAT。我們期望我們的NAT是第二種,哈哈,如果你的NAT剛好是第一種,那麼很可能會有很多P2P軟體失靈。(可以慶幸的是,現在絕大多數的NAT屬於後者,即Cone NAT)
好了,我們看到,通過NAT,子網內的電腦向外連結是很容易的(NAT相當於透明的,子網內的和外網的電腦不用知道NAT的情況)。
但是如果外部的電腦想訪問子網內的電腦就比較困難了(而這正是P2P所需要的)。
那麼我們如果想從外部傳送一個資料報給局內網的電腦有什麼辦法呢?首先,我們必須在局內網的NAT上打上一個「洞」(也就是前面我們說的在NAT上建立一個Session),這個洞不能由外部來打,只能由局內網內的主機來打。
而且這個洞是有方向的,比如從內部某台主機(比如:192.168.0.10)向外部的某個IP(比如:219.237.60.1)傳送一個UDP包,那麼就在這個局內網的NAT設備上打了一個方向為219.237.60.1的「洞」,(這就是稱為UDP Hole Punching的技術)以後219.237.60.1就可以通過這個洞與局內網的192.168.0.10聯係了。(但是其他的IP不能利用這個洞)。
哈哈,現在該輪到我們的正題P2P了。
有了上面的理論,實現兩個局內網的主機通訊就差最後一步了:那就是雞生蛋還是蛋生雞的問題了,兩邊都無法主動發出連接請求,誰也不知道誰的公共外網位址,那我們如何來打這個洞呢?我們需要一個中間人來聯係這兩個局內網主機。
現在我們來看看一個P2P軟體的流程,以下圖為例:
Server S (219.237.60.1)
|
|
+----------------------+----------------------+
| |
NAT A (外網IP:202.187.45.3) NAT B (外網IP:187.34.1.56)
| (局內網IP:192.168.0.1) | (局內網IP:192.168.0.1)
| |
Client A (192.168.0.20:4000) Client B (192.168.0.10:40000)
首先,Client A登入伺服器,NAT A為這次的Session分配了一個連接阜60000,那麼Server S收到的Client A的位址是202.187.45.3:60000,這就是Client A的外網位址了。同樣,Client B登入Server S,NAT B給此次Session分配的連接阜是40000,那麼Server S收到的B的位址是187.34.1.56:40000。
|