2013-10-26 139 views
2

我有一個問題。我有一個客戶端程序,用於偵聽服務器的UDP端口。這些服務器發送數據包(每秒一個),其內部有TCP端口。這些端口是如何識別服務器的。當這樣的數據包第一次到達時,服務器被存儲在集中式集合中。如果服務器在5秒內未能發送這些數據包,則認爲此服務器處於脫機狀態並從集合中刪除。幾個線程在一個UDP端口上偵聽?

我想要做的是爲每個服務器產生一個新的線程。該線程只應該監聽一臺服務器。如果服務器超時,線程將從服務器中刪除服務器並自行終止。

我已經使用ThreadPool實現了該功能,但它根本不起作用。我到目前爲止的想法是,這可能是由於不同線程的檢查,如果一個數據包確實是它應該監聽的數據包,那麼傳入數據包的順序就會完全混亂,導致混亂的移除和添加服務器集合。

是否有多個線程可以監聽單個UDP端口的可能性?我如何才能實現預期的行爲?

謝謝你的幫助!

編輯

在主線程:

datagramSocket = new DatagramSocket(udpPort); 
datagramSocket.setReuseAddress(true); 

,以及在新的線程。再次

java.net.BindException: Address already in use 
[java]  at java.net.PlainDatagramSocketImpl.bind0(Native Method) 
[java]  at java.net.AbstractPlainDatagramSocketImpl.bind(AbstractPlainDatagramSocketImpl.java:95) 
[java]  at java.net.DatagramSocket.bind(DatagramSocket.java:376) 
[java]  at java.net.DatagramSocket.<init>(DatagramSocket.java:231) 
[java]  at java.net.DatagramSocket.<init>(DatagramSocket.java:284) 
[java]  at java.net.DatagramSocket.<init>(DatagramSocket.java:256) 
[java]  at proxy.ServerHandler.<init>(ServerHandler.java:32) 
[java]  at proxy.DatagramSocketListener.run(DatagramSocketListener.java:59) 
[java]  at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) 
[java]  at java.util.concurrent.FutureTask.run(FutureTask.java:262) 
[java]  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
[java]  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
[java]  at java.lang.Thread.run(Thread.java:744) 

編輯2

謝謝!但是,現在在主線程:

datagramSocket = new DatagramSocket(); 
datagramSocket.setReuseAddress(true); 
datagramSocket.bind(new InetSocketAddress(udpPort)); 
在新線程

datagramSocket = new DatagramSocket(); 
datagramSocket.setReuseAddress(true); 
datagramSocket.connect(server.getAddress(), udpPort); 

結果:

[java] java.net.SocketException: already bound 
[java]  at java.net.DatagramSocket.bind(DatagramSocket.java:360) 
[java]  at proxy.DatagramSocketListener.<init>(DatagramSocketListener.java:33) 
[java]  at proxy.ProxyCli.<init>(ProxyCli.java:74) 
[java]  at proxy.ProxyCli.main(ProxyCli.java:30) 

但它是我第一次初始化一個DatagramSocket ???

回答

-1

在新線程的同一端口上創建一個新套接字。您必須在所有套接字上設置SO_REUSEADDR,包括原始套接字才能實現此功能。然後,將新的插座連接到所需的目標。然後該套接字將只接收來自該目標的數據報。

+0

謝謝,但我總是得到一個java.net.BindException:地址已被使用。我在兩個套接字上使用datagramSocket.setReuseAddress(true)。 – user2923837

+0

你需要在綁定之前調用它。 – EJP

+0

謝謝,但還有另一個問題。 – user2923837