2011-03-18 141 views
7

背景:我正在寫一個簡單的UDP應用程序來ping一個測試版服務器我每分鐘管理一次或多次,告訴我它仍然在運行(我可以' t在服務器上爲那些想知道的啓用ping)。我打算在手機上運行此命令,以在服務器不再響應時發出警告。Android:java.net.DatagramSocket.bind:無效的參數異常

我試圖用看似簡單的java.net.DatagramSocket中這樣:

try 
    { 
     socket = new DatagramSocket(); 
     socket.bind(null); 
    } 
    catch (SocketException e) 
    { 
     System.out.println(e.toString()); 
     throw e; 
    } 

也讓我說,我已經通過Android清單啓用上網權限和如果我刪除了使用條款要做到這一點,我得到了一個權限錯誤,所以我確信這個工作正常。當我將此代碼下載到Android虛擬設備(AVD)並執行它時,在調用bind()時出現以下異常:

03-17 19:07:39.401:INFO/System.out 338):java.net.BindException:無效的參數

根據this文檔中,空參數是正確的:

公共無效綁定(SocketAddress的localAddr)

自:API級別1

將此套接字綁定到由localAddr指定的本地地址和端口。 如果此值爲空,則使用有效本地地址上的任何空閒端口

但不信任的文檔,我決定列舉我的設備上的IP地址是這樣的:

ArrayList<NetworkInterface> allInterfaces = Collections.list(NetworkInterface.getNetworkInterfaces()); 

    NetworkInterface eth = allInterfaces.get(0); 

    InetSocketAddress addr = new InetSocketAddress(eth.getInetAddresses().nextElement(), port); 

    try 
    { 
     socket = new DatagramSocket(); 
     socket.bind(addr); 
    } 
    catch (SocketException e) 
    { 
     System.out.println(e.toString()); 
     throw e; 
    } 

當我通過代碼,它的偉大工程,我可以看到兩個IP地址AVD,但我在bind()調用中得到完全相同的異常。有沒有人看到我可能會失蹤?我將繼續研究並希望爲我自己的問題發佈一個解決方案,但我希望有人能夠爲我做到這一點。

+0

端口號?它是否在有效範圍內? – 2011-03-18 07:56:50

+0

嘗試使用不同的端口號。 – 2011-03-18 07:57:28

回答

9

[編輯:如果你看到我以前的迴應,我在做一個測試改變兩個可變的經典調試錯誤,這是另外一個是解決我的問題。]

我發現這個問題。這是我聲明DatagramSocket看起來會導致問題的方式。如果我使用DatagramChannel以下面的方式打開DatagramSocket,則bind()調用成功。

 DatagramChannel channel = DatagramChannel.open(); 
     DatagramSocket socket = channel.socket(); 
+0

不知道爲什麼,但這也適用於我。 – 2013-05-13 07:57:44

+3

新的DatagramSocket(null); – 2013-08-22 00:52:17

2

我已經過這個問題無論是偶然和已經找到了原因:如果你調用參數構造函數new DatagramSocket(),這創造「,這是綁定到任何可用的端口本地主機上的UDP數據報套接字使用通配符地址「(根據API文檔)。所以這實際上意味着Socket已經綁定了。我的「修復」,這是如下:

 SocketAddress socketAddress = new SocketAddress(yourInetAddress, yourPort); 
     DatagramSocket serverSocket = new DatagramSocket(null); 
     serverSocket.bind(socketAddress); 

這明確地創建一個未綁定的套接字(通過DatagramSocket (SocketAddress localAddr)構造函數),從而可以綁定套接字反過來。

這可能是比創建不必要的頻道更優雅的解決方案。

P.S .:奇怪的是,這是DatagramSocket不同於TCP ServerSocket:後者的無參數構造函數將創建一個未綁定的ServerSocket,而不會觸發此問題。