TCP打洞和UDP打洞的區別 (相互直接訪問)


為什么網上講到的P2P打洞基本上都是基於UDP協議的打洞?難道TCP不可能打洞?還是TCP打洞難於實現? 
    假設現在有內網客戶端A和內網客戶端B,有公網服務端S。 
    如果A和B想要進行UDP通信,則必須穿透雙方的NAT路由。假設為NAT-A和NAT-B。 
     
    A發送數據包到公網S,B發送數據包到公網S,則S分別得到了A和B的公網IP, 
S也和A B 分別建立了會話,由S發到NAT-A的數據包會被NAT-A直接轉發給A, 
由S發到NAT-B的數據包會被NAT-B直接轉發給B,除了S發出的數據包之外的則會被丟棄。 
所以:現在A B 都能分別和S進行全雙工通訊了,但是A B之間還不能直接通訊。 

    解決辦法是:A向B的公網IP發送一個數據包,則NAT-A能接收來自NAT-B的數據包 
並轉發給A了(即B現在能訪問A了);再由S命令B向A的公網IP發送一個數據包,則 
NAT-B能接收來自NAT-A的數據包並轉發給B了(即A現在能訪問B了)。 

    以上就是“打洞”的原理。 

    但是TCP和UDP在打洞上卻有點不同。這是因為伯克利socket(標准socket規范)的 
API造成的。 
    UDP的socket允許多個socket綁定到同一個本地端口,而TCP的socket則不允許。 
    這是這樣一個意思:A B要連接到S,肯定首先A B雙方都會在本地創建一個socket, 
去連接S上的socket。創建一個socket必然會綁定一個本地端口(就算應用程序里面沒寫 
端口,實際上也是綁定了的,至少java確實如此),假設為8888,這樣A和B才分別建立了到 
S的通信信道。接下來就需要打洞了,打洞則需要A和B分別發送數據包到對方的公網IP。但是 
問題就在這里:因為NAT設備是根據端口號來確定session,如果是UDP的socket,A B可以 
分別再創建socket,然后將socket綁定到8888,這樣打洞就成功了。但是如果是TCP的 
socket,則不能再創建socket並綁定到8888了,這樣打洞就無法成功。

 

http://www.cnblogs.com/key-ok/p/4367386.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM