2012-11-16 99 views
9

我正嘗試在兩個Android設備之間創建IPv6 TCP連接。但是,創建套接字總是失敗。Android上的IPv6套接字

如果我實例是這樣的:

Inet6Address dest = (Inet6Address) InetAddress.getByName(addressString); 
Socket socket = new Socket(dest, portNumber); 

我得到以下異常:

java.net.ConnectException: failed to connect to *address* (port *portNumber*): connect failed: EINVAL (Invalid argument) 

如果我不是實例我IPv6Address對象是這樣的:

Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces(); 
NetworkInterface wifiInterface = null; 
while (networkInterfaces.hasMoreElements()) { 
    NetworkInterface networkInterface = networkInterfaces.nextElement(); 
    if (networkInterface.getDisplayName().equals("wlan0") || networkInterface.getDisplayName().equals("eth0")) { 
    wifiInterface = networkInterface; 
    break; 
    } 
} 
Inet6Address dest = Inet6Address.getByAddress(null, addressBytes, wifiInterface); 
Socket socket = new Socket(dest, portNumber); 

我得到調用Socket構造函數時發生此錯誤:

java.net.ConnectException: failed to connect to *address* (port *portNumber*): connect failed: EADDRNOTAVAIL (Cannot assign requested address) 

這種情況發生在Galaxy Nexus與果凍豆和Nexus One與薑餅上。

我做錯了什麼?創建這樣的套接字的正確方法是什麼?

另外:This post建議使用構造

Inet6Address getByAddress (String host, byte[] addr, int scope_id) 

我將不得不使用在這種情況下scope_id?

+0

顯示我們的dest和portNumber變量值。 –

+0

第一個變體中的addressString值例如爲「fe80 :: 9221:55ff:fee3:3303」。 相應的addressBytes數組是[-2,-128,0,0,0,0,0,0,110,33,85,-1,-2,-29,51,3]。 對於我使用的端口3109.這應該是一個隨機端口,不用於其他任何事情。 –

+0

偶然是你連接的路由器支持IPv6? –

回答

5

由於您的IP地址是本地鏈接,因此它可能必須使用作用域ID或接口創建,以便操作系統知道綁定到哪個接口。至於指定scope_id,Android文檔似乎有點缺乏。 Oracle文檔here指示作用域ID是系統特定的,不能通過編程方式確定。

所以,我會嘗試使用替代工廠方法,您明確指定您要使用的NetworkInterface。詳情請參閱here。 NetworkInterface類中有方法可以發現系統上存在哪些接口。

+0

謝謝!但是,這不是我在第二個變體中使用的工廠方法,它只拋出一個稍微不同的異常? –

+0

你是對的!對於那個很抱歉!您是如何找到您在此嘗試中使用的NetworkInterface對象的? – schtever

+0

我遍歷所有可用的接口,並按名稱選擇一個我需要的接口,並驗證我確實找回了正確的接口。 爲了清晰起見,我在原始帖子中添加了代碼。 –