2015-11-25 31 views
0

我正在使用UDP客戶端與我無法控制的服務器進行通信。部分與此服務器通信的要求是我必須向服務器提供一個UDP端口號(作爲消息的一部分)以進行回覆通信。需要幫助讓我的Java UDP客戶端應用程序工作

我有幾個班在我的應用程序,需要一個DatagramSocket,代表不同的請求到該服務器,所以我創建了一個靜態類:

package mypackage; 

import java.net.DatagramSocket; 
import java.net.InetSocketAddress; 
import java.net.SocketException; 

public class DatagramSocketGrabber { 

    public DatagramSocketGrabber(){} 

    public static DatagramSocket getSocket() throws SocketException { 
     DatagramSocket newSocket = new DatagramSocket(); 
     InetSocketAddress newSocketAddress = new InetSocketAddress(15346); 
     newSocket.bind(newSocketAddress); 
     return newSocket; 
    } 
} 

在我的main()類,我抓住這個插座連接,並用它在我的應用程序:

package mypackage; 

import java.net.DatagramSocket; 
import java.net.SocketException; 

public class MyApp { 
    public static void main(String[] args){ 
     DatagramSocket mySocket = null; 

     try { 
      mySocket = DatagramSocketGrabber.getSocket(); 
     } catch(SocketException se){ 
      System.out.println(se); 
     } 

     DSClass01 class01 = new DSClass01(mySocket); 
     DSClass02 class02 = new DSClass02(mySocket); 
     DSClass03 class03 = new DSClass03(mySocket); 

     mySocket.close(); 
    } 
} 

但是,每當我跑我的申請,我總是得到錯誤:

java.net.SocketException: already bound

需要知道

的UDP服務器是我的機器(本地主機)上,但它是一個編譯的應用程序,所以我無法檢查其代碼。是的,它來自可靠的來源。

沒有防火牆或網絡問題,因爲它是一個獨立的計算機,一切都很開放。

在我創建靜態DatagramSocketGrabber類之前,我在所有消息類中創建了一個新的DatagramSocket,並且服務器能夠成功接收我的消息。

但是,我創建靜態類的原因是因爲我沒有收到任何回覆,並且我確定這是因爲我沒有將套接字綁定到「固定」接收端口。爲了做到這一點,並且能夠在我的所有消息類中使用綁定套接字,我想我需要創建一個DatagramSocket創建類,以便擁有一個可以傳遞的綁定套接字。

+0

看起來好像你試圖綁定端口15346多次 – malinator

回答

0

好的......我想通了。經過一天的谷歌搜索,我發現this在StackOverflow上發佈。我所要做的就是從

DatagramSocket newSocket = new DatagramSocket(); 

改變DatagramSocketGrabber到

DatagramSocket newSocket = new DatagramSocket(null); 

,一切工作正常。解釋是這樣的:

Calling the no-arg constructor for a datagram socket will cause it to bind to a random, available port. Once bound, further attempts to (re)bind will throw a socket exception (with the error you were seeing). To 'defer' binding, you instead create the datagram socket in an unbound state (by passing a null in the constructor), then calling bind later on.

感謝Perception爲他/她的答案!

1

我的猜測,因爲你不分享拋出SocketException的代碼是下面的一個。

1)您在程序中第二次調用DatagramSocketGrabber.getSocket();,因此發生SocketException。

2)您留下一些代碼綁定到相同的端口(如new InetSocketAddress(15346);

嘗試搜索您的插座結合(15346碼),並嘗試找出是否有任何其他DatagramSocketGrabber.getSocket();打電話給你程序。同時,您可以將DatagramSocketGrabber更改爲單例,並將DatagramSocket保留爲屬性,因此您可以始終調用您的單例,而不是將套接字傳遞給所有方法。

+0

這是一個關於使用單例作爲DatagramSocketGrabber的奇妙建議......謝謝!至於項目1和2,他們不是問題,但謝謝。 – Brian

+0

此外,拋出異常的代碼是我列出的main()方法中的「try」塊。 – Brian