我有问题。我有一个客户端程序,它侦听服务器的UDP端口。这些服务器使用其TCP端口发送数据包(每秒一个)。这些端口是识别服务器的方式。当这样的数据包第一次到达时,服务器存储在集中收集中。如果服务器无法发送这些数据包5秒钟,则该服务器将被视为脱机并从集合中删除。
我想做的是为每个服务器生成一个新线程。该线程应该只监听一个服务器。如果服务器超时,则线程将从集合中删除服务器并终止自身。
我用 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 ???
答案 0 :(得分:-1)
在新线程的同一端口上创建一个新套接字。您必须在包括原始套接字在内的所有套接字上设置SO_REUSEADDR才能实现此目的。然后,将新套接字连接到所需目标。然后该套接字将只接收来自该目标的数据报。