從上面的描述,咱們能夠得出兩個結論,作好P2P應用至少須要解決兩個問題:1.實現內網之間機器的網絡通訊。2.須要解決UDP出現的數據傳輸不穩定問題。html
先說第一點,內網穿透,假設一臺在NAT211.133.*後的192.168.1.77:8000要向NAT211.134.*後的192.168.1.88:9000發送數據,假設你向211.134.*這個IP地址的9000端口直接發送數據包,則數據包在到達NAT211.134.*以後,會被當作無效非法的數據包被丟棄,NAT在此時至關於一個防火牆,會對沒有創建起有效SESSION的數據包進行拒絕轉遞。固然,你也不能直接用內網地址192.168.1.88進行發送數據包,這就比如你在廣州要打電話到上海的某個地方,若是你不加區號,直接撥打區域內電話是件很愚蠢的事。
那咱們要怎麼實現穿透?首先咱們要認識NAT設備,NAT英文全拼是Network Address Translator(網絡地址轉換器),說白了就是凡是通過NAT發出去的數據包,都會經過必定的端口轉換(而非使用原端口)再發出去,也就是說內網和外網之間的通訊不是直接由內網機器與外網NAT進行,而是利用內網對外網的NAT創建起SESSION與外網NAT的SESSION進行。而後,根據SESSION的不一樣,NAT主要分紅兩種:Symmetric NAPT以及CONE NAPT。簡單的說,Symmetric NAPT是屬於動態端口映射的NAT,而CONE NAPT是屬於靜態端口映射的NAT。而市場上目前大多屬於後者,CONE的英文意思錐,意思就是一個端口能夠對外部多臺NAT設備通訊。這個也正是咱們作點對點穿透的基本,是咱們所但願的,不然如今的大部分點對點軟件將沒法正常使用。程序員
像上面的例子,NAT211.133.*和NAT211.134.*之間須要進行通訊,但開始不能直接就發數據包,咱們須要一箇中間人,這個就是外部索引服務器(咱們假設是211.135.*:7000),當NAT211.133.*向211.135.*:7000發送數據包,211.135.*:7000是能夠正常接收到數據,由於它是屬於對外型開放的服務端口。當211.135.*:7000收到數據包後能夠獲知NAT211.133.*對外通訊的臨時SESSION信息(這個臨時的端口,假設是6000會過時,具體的時間不一樣,但我我的的測試是每30秒發送一個心跳包keep住鏈接以保證端口維持住通訊鏈接不斷開),索引服務器此時應將此信息保存起來。而同時,NAT211.134.*也在時刻向索引服務器發送心跳包,索引服務器就向NAT211.134.*發送一個通知,讓它向NAT211.133.*:6000發送探測包(這個數據包最好多發幾個),NAT211.133.*在收到通知包以後再向索引服務器發送反饋包,說明本身已經向NAT211.133.*:6000發送了探測包,索引服務器在接收到反饋包以後再向NAT211.133.*轉發反饋包,NAT211.133.*在接收到數據包以後再向本來要請求的NAT211.134.*發送數據包,此時鏈接已經打通,實現穿透,NAT211.134.*會將信息轉發給192.168.1.88的9000端口。
對於Symmetric NAPT的狀況,網上有人說能夠經過探測端口的方式,不過成功率並不高,我建議可用服務器進行中轉。另外,最好在數據包發送前先檢測是否進行的是同個NAT的狀況,也就是內網發內網,若是是,直接發送便可,而無需經過外網再繞回來。
其次關於第二點,解決UDP傳輸的不穩定問題,其實這裏涉及到另外一個方面的知識,就是滑動窗口的東西,能夠開一個緩衝區用於循環接收數據以及重組,另外加上超時重發機制以及確認發送機制,有點像TCP的傳輸原理,不過若是處理的好,效率絕對比採用TCP的方式要高。另外對於滑動窗口機制的知識在這裏就不說了,有興趣能夠上網找找資料。服務器
出處:http://www.cnblogs.com/openso2009/archive/2009/09/23/1572448.html網絡