2014-03-28 102 views
4

我需要的是,我將打開一個UDP服務器在X端口(本地機器)偵聽和machine(public IP)可以發送UDP數據包給我。我的機器沒有public IP。基本上我需要stun昏迷服務器的混亂

我正在測試stuntman服務器/客戶端項目。我在服務器(公共IP)上運行stuntman-server。在我的系統中運行客戶端(本地IP)。我要求爲9999端口映射IP /端口。

./stunclient --mode full --protocol udp --localport 9999 stun.server.ip 

Stun服務器返回一個IP和端口。我做了什麼,然後,在我的本地系統打開一個UDP服務器(使用Java),並開始在9999端口偵聽,other machine (which has public IP)發送UDP消息給STUN服務器返回mapped IP/port。但我無法收到任何數據。你可以假設我的服務器/客戶端代碼(用java編寫)在本地網絡中工作正常。

流量:

My machine ->>>>>stun request for 9999 port and my ip ------> stun server 
My machine <<<<<<<<<<<<<<<<<<mapped ip/port <<<<<<<<<<<<<<< stun server 
My machine : Run JAVA udp server socket in 9999 port 

My machine <<<<<<<<<<<<<<<<<<<UDP message to mapped ip/port<<<<<< other public machine 
      xxxxxxxxxxxxxxxxxxxNot workingxxxxxxxxxxxxxxxxxxxxxxxx 

回答

7

你沒有發佈stunclient運行的結果,但我想它看起來像下面這樣:

$ stunclient --mode full --localport 9999 stun.stunprotocol.org 
Binding test: success 
Local address: 192.168.1.8:9999 
Mapped address: 1.2.3.4:9999 
Behavior test: success 
Nat behavior: Endpoint Independent Mapping 
Filtering test: success 
Nat filtering: Address and Port Dependent Filtering 

我要去猜測,你的行爲測試是「獨立於終端」,過濾測試是「地址和端口相關」,因爲這些在家庭中最常見,並且大部分與您上面描述的相匹配。 (又稱「限制端口的NAT」)。

無論如何,這意味着你已經在你自己和STUN服務器之間創建了一個端口映射。在上面的例子中,我的公共IP地址是1.2.3.4。這是常見的,但並非總是如此,我的本地端口(9999)與公共端口相同。

內部,NAT還記錄着一個邏輯表如下所示:

------------------------------------------------------------------------------------ 
||  LOCAL IP | LOCAL PORT || EXT PORT || REMOTE IP  | REMOTE PORT || 
||================================================================================|| 
|| 192.168.1.8 | 9999  || 9999  || 107.23.150.92 | 3478  || 
------------------------------------------------------------------------------------ 

因爲你從端口9999發送出去的數據包到STUN服務器(107.23.150.92),該NAT創建一個端口映射條目在桌上幾分鐘。當數據包從互聯網到達NAT /路由器時,它會查詢表格。當響應從STUN服務器的IP:端口返回時,NAT能夠基於上表中的「遠程」字段將其轉發到NAT後面的計算機。

但是,您和希望從中接收數據的「其他公共機器」之間沒有端口映射。我們假設另一臺機器的IP地址是2.4.6.8,並且它試圖從它的本地端口8888發送。表中的NAT仍然沒有任何東西來將流量從2.4.6.8:8888映射到後面的主機NAT。因此,當流量從不在表中的主機到達NAT時,NAT只知道將數據包丟棄在地面上。有一種稱爲「Cone NAT」的NAT分類,這可以起作用,但這些分類並不常見。

在你的情況下,有一個簡單的解決方法。從STUN服務器獲取端口映射後,從同一本地端口(9999)發送另一個數據報到您想從其接收數據的遠程主機(和遠程端口)。遠程主機可以簡單地忽略這個數據包,但它有效地創建你的NAT

------------------------------------------------------------------------------------ 
||  LOCAL IP | LOCAL PORT || EXT PORT || REMOTE IP  | REMOTE PORT || 
||================================================================================|| 
|| 192.168.1.8 | 9999  || 9999  || 107.23.150.92 | 3478  || 
|| 192.168.1.8 | 9999  || 9999  || 2.4.6.8   | 8888  || 
------------------------------------------------------------------------------------ 

這個簡單的1字節的數據包到2.4.6另一個端口映射條目。8:8888允許NAT將流量從該地址轉發回NAT後面的主機。

換句話說,利用自己的網絡流量的命名:

My machine:9999 ---->[STUN BINDING REQUEST]--->stun server:3478 

My machine:9999 <----[STUN BINDING RESPONSE mapped IP:port]<--- stun server:3478 

My machine:9999 [Open socket on port 9999] 

My machine:9999 ---->[1 byte datagram] -------> 'other:8888' 

My machine:9999 <---- [UDP to public IP:port obtained in step 2]<----'other:8888' 

通常,在一個正常的P2P流量,兩個端點與STUN服務器工作,發現他們的端口映射。然後使用另一個服務來互相交換IP:端口信息。從你所描述的,你手動交換你的程序之間的這些值,這是很好的測試。

如果另一臺機器在公共互聯網上,您在技術上不需要STUN。第一臺機器(在NAT後面)可以直接發送到遠程IP和端口來說「給我發送一些數據」。遠程端只是檢查此消息的對端地址和端口,以決定發回的位置。端口映射已經被創建。一些RTSP客戶端假設服務器是公開的

我對套接字NAT穿越的基礎知識的回答是here

我碰巧知道STUNTMAN的開發者。他是一個相當不錯的人,很帥,很聰明。他們也說他和我看起來很像,並且與我們的姓名拼寫很接近。如果您有關於STUN和NAT遍歷的問題,可以隨時直接給他發郵件。