我試圖在NAT之後的兩臺計算機之間建立連接。我無法打開任何端口。我想使用一名將在互聯網上的經紀人,他將能夠與另外兩人交流。之後,我想在這兩個之間建立一個隧道。我使用Python,並且我正在嘗試爲這個代理編寫代碼。 我該如何開始呢?在NAT之後的兩臺計算機之間建立連接
回答
你想做什麼是可能的,幾乎是例行的(至少對於UDP)。這就是所謂的NAT打孔。它不適用於全球所有的NAT,但它可以與許多設備一起使用,包括大多數當前家庭路由器的大多數設置。
其基本思想是,對於大多數路由器,如果您發送傳出數據包,它會將來自同一端點的任何傳入數據包轉發回給您。否則,NAT根本無法工作,對吧?所以,如果你和我都試圖在同一時間與對方的公共地址對話,我們其中一個人會及時在他的NAT中「打出一個空洞」來接收信息。另一個可能會錯過最初的信息,因爲他太晚打了個洞,但他會收到另一個人發來的下一個回覆,之後,一切正常。
但是,這裏有一些技巧。
首先,您需要知道您的公開地址。你可以直接看到是你在NAT內的私人地址,所以你需要一個NAT以外的服務器來告訴你你來自哪裏。有一個標準,稱爲STUN。不僅有多個可以自己構建和運行的免費實現,互聯網上有多個開放的STUN服務器;谷歌更新列表。
至少,你有一個私人地址和你的公共地址,你真的想給其他人所有他們,而不只是一個。 (如果你只給我你的公共地址,而且事實證明我們在同一個NAT上,我們可能無法相互交談。)如果你有多個NIC,它會變得更加複雜,或者你是在具有多層NAT的企業局域網上等。但是如果你給我一大堆地址,我怎麼知道使用哪一個?簡單來說,我可以嘗試從每個本地地址連接到每個地址,而第一個工作的地方就是我一直使用的地址。我們顯然需要某種協議,所以你可以告訴我他們中的一個是否已經工作,但它可能很簡單。
另外,請注意,當我在這裏說「地址」時,這並不僅僅意味着IP地址,而是IP地址加上端口。畢竟,NAT可以並且可以將端口與地址一起轉換,並且您在NAT中打出的「孔」通常是端口特定的。因此,您需要使用您將用於真正通信的相同源端口和目標端口進行協商。 (實際上,這裏有一些棘手的問題,這是由鏈接文檔解釋的,但現在讓我們一起瀏覽它們。)
當穿孔不起作用,並且您需要通過服務器回退代理,你不希望代碼看起來完全不同;你最終不得不把所有東西都寫兩遍,並且在調試時遇到很大問題。幸運的是,這裏有一個標準的解決方案,叫做TURN,它使得它看起來像是他們實際上直接對話,即使他們正在通過中繼談話。再次有免費的實現,但當然沒有開放的TURN服務器供您使用(因爲這會花費很多帶寬)。
同時,一旦你知道你的公開地址,你必須告訴我它是什麼,反之亦然。顯然,我們需要一些輔助通道來討論,如特殊的「介紹者」或「大廳」服務器。通常,您將產生一個點對點連接作爲一些服務器中介連接的旁枝。例如,我們可能一起在IRC頻道或XMPP/Jabber聊天網絡中,決定我們想要點對點通信(以避免竊聽,或共享巨大的電子表格文件,或者玩一個沒有巨大數量的遊戲落後)。
有一個叫做ICE的標準把這一切聯繫在一起;只要我們有一個共享側通道和一個STUN(可能是TURN)服務器的列表,ICE讓我們在可能的情況下協商一個對等連接(如果沒有的話,則回落到TURN)。
ICE支持是SIP和其他一些協議的一部分,所以如果您使用其中一種協議的庫,您可能只需要瞭解如何爲它提供一個STUN和TURN服務器列表以及而已。如果沒有,那麼可能有用於ICE的庫。如果沒有,那麼肯定有STUN和TURN庫(如果沒有,它們都是非常簡單的協議),所以你可以自己做談判。
當然,您不必使用這些標準中的任何一個,但您一定要閱讀他們的工作內容,以及他們爲什麼要這樣做。 (另外,請記住,人們現在正在路由器專門做ICE更好地工作,以及有什麼不同,你創造這不會是真的。)
我已鏈接到維基百科的文章,因爲以上他們首先對這些技術的工作原理和背後的基本原理進行了非常簡單的概述。有詳細的參考規範,開始的示例代碼,要使用的庫等的更好的來源,但一般來說維基百科鏈接到您需要的一切。
非常感謝您的回答。我有最後一個問題。我看到如何擁有所有客戶的公共IP。但如何擁有港口? – 2014-10-09 09:00:54
@MathieuLepage:好問題。由於NAT可以重新映射端口,因此您必須通過STUN獲取公共端口,並通過您使用的任何輔助渠道或介紹人宣佈該地址,就像地址一樣。有些協議(包括SIP)嘗試使用相鄰端口範圍的技巧,但許多NAT會打破這些技巧,所以如果可以避免的話,那麼做。無論如何,如果你正在使用ICE,它會與其餘的談判一起處理。 – abarnert 2014-10-09 18:46:04
但冰可以使用沒有眩暈和轉彎? – 2014-10-09 20:48:26
- 1. 如何在兩臺防火牆後面的幾臺計算機之間建立TCP連接?
- 2. 建立計算機之間的套接字連接?
- 3. 在兩臺計算機之間移動連接和實例
- 4. 在遠程計算機之間建立局域網連接
- 5. 如何模擬兩臺計算機之間的無線連接?
- 6. 在主機之間建立TCP連接
- 7. 兩臺電腦之間沒有開放端口的通信,使用第三臺計算機來建立連接
- 8. 在兩臺計算機之間建立一個連接,其間有一個網站
- 9. 計算機之間的RMI連接
- 10. 同步連接LAN電纜的兩臺Windows 7計算機之間的時間
- 11. 如何在python中的兩臺連接的計算機之間傳輸文件?
- 12. 如何建立沒有公共IP的兩臺計算機之間的cconnection
- 13. 如何在兩部手機之間建立p2p連接?
- 14. 建立兩個Android手機之間的P2P連接?
- 15. 使用WiFi連接在兩臺計算機之間發送數據(文本)C#
- 16. 不能連接兩臺計算機之間在同一局域網插座
- 17. 通過無線連接的兩臺計算機之間的信息交換
- 18. 2臺計算機之間的ipsec
- 19. 如何在不同網絡的NAT後面的兩個客戶端之間建立TCP連接?
- 20. 建立兩個獨立的機器之間的SSH連接使用3系統
- 21. 如何在兩臺計算機之間傳輸數據?
- 22. 如何在兩臺計算機之間共享svn存儲庫
- 23. 如何在兩臺計算機之間同步Angular CLI版本?
- 24. 如何在兩臺計算機之間傳遞大量數據
- 25. TCP/IP在兩臺計算機之間不工作
- 26. 在不同地點建立虛擬機器之間的連接
- 27. 計算兩臺攝像機之間的基線距離(圖像)
- 28. 與兩臺計算機之間的通信與c#
- 29. 兩臺遠程計算機之間的同步(時鐘)
- 30. 局域網內兩臺計算機之間的數據傳輸
有一百種方法可以做到這一點。 NAT後面的計算機將不得不啓動與常見的互聯網代理的連接。實驗的一個簡單選項是zeromq,它有幾個可用於路由消息的工具。你甚至可以設置一個在兩臺服務器之間轉發請求的asyncio服務器。 – tdelaney 2014-10-08 22:50:53
嗯,但是可以將服務器連接到代理,然後將客戶連接到此代理,並在這兩者之間建立隧道?沒有再次使用經紀人 – 2014-10-08 22:55:45
不,所有流量都必須經過經紀人。我假設這些機器位於不同的NAT之後,並且您不希望在NAT之後進行端口轉發。如果是這樣,這些機器是彼此不可見的,並且需要某種通用代理/經紀人進行通信。 – tdelaney 2014-10-08 23:09:24