我在Java项目中需要监听3个不同的UDP端口。我按照以下方式实现了我的系统:
我有一个名为UDPMessageListener的类,它实现了Runnable接口。我想要创建3个线程,以此对象作为运行实例。
我有一个名为“UDPPacketProcessor”的接口,其中只有一个onPacketReceived方法。
每个UDPMessageListener都有一个UDPPacketProcessor实例,并将UDP数据包定向到已注册为其UDPPacketProcessor的对象。
我还有一个名为DatabaseProc的类,它需要为来自3个不同UDP端口的消息提供服务。DatabaseProc实现了UDPPacketProcessor以向这3个UDPMessageListener类注册自身。
理论上,根据我的Java知识,不应该有任何问题,3个Runnable线程监听3个端口,并在收到数据包时调用我的主单例对象的方法。然而,当我运行程序时,只有一个端口被监听。我发现只有HBMessageListener正常工作,其他两个不起作用。当我绕过HBMessageListener(注释掉我运行它的那一行)后,我现在可以看到只有AlarmMessageListener起作用。我错在哪里了?
UDPMessageListener.java
public class UDPMessageListener implements Runnable {
int port;
byte[] receiveData;
DatagramSocket udpListeningSocket;
UDPPacketProcessor processor;
public UDPMessageListener(UDPPacketProcessor listener,int localPort){
port = localPort;
this.processor = listener;
receiveData = new byte[SRPDefinitions.BYTE_BUFFER_MAX_LENGTH];
try {
udpListeningSocket = new DatagramSocket(port);
} catch (SocketException e) {
System.out.println("Socket bind error in port: " + port);
e.printStackTrace();
}
}
@Override
public void run() {
while(true){
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
try {
udpListeningSocket.receive(receivePacket);
System.out.println("Received UDP Packet from Port:" + port);
processor.onPacketReceived(receivePacket, port);
} catch (IOException e) {
System.out.println("UDP Listener end up with an exception:");
e.printStackTrace();
}
}
}
}
UDPPacketProcessor.java
public interface UDPPacketProcessor {
public void onPacketReceived(DatagramPacket receivedPacket,int localPort);
}
DatabaseProc.java
public class DatabaseProc implements UDPPacketProcessor{
private static DatabaseProc instance = null; // for singleton.
byte[] receiveData;
byte[] sendData;
ByteBuffer systemMessageByteBuffer;
UDPMessageListener HBMessageListener;
UDPMessageListener AlarmMessageListener;
UDPMessageListener TrackMessageListener;
private DatabaseProc(){
receiveData = new byte[SRPDefinitions.BYTE_BUFFER_MAX_LENGTH];
sendData = new byte[SRPDefinitions.BYTE_BUFFER_MAX_LENGTH];
HBMessageListener = new UDPMessageListener(this,SRPDefinitions.HB_PORT);
AlarmMessageListener = new UDPMessageListener(this,SRPDefinitions.ALARM_PORT);
TrackMessageListener = new UDPMessageListener(this,SRPDefinitions.TRACK_PORT);
}
public void run(){
runListeners();
}
private void runListeners(){
HBMessageListener.run();
AlarmMessageListener.run();
TrackMessageListener.run();
}
public static DatabaseProc getInstance(){
if(instance == null){
instance = new DatabaseProc();
}
return instance;
}
@Override
public void onPacketReceived(DatagramPacket receivedPacket, int localPort) {
String strIPAddress =receivedPacket.getAddress().toString();
ByteBuffer buffer = ByteBuffer.allocate(receivedPacket.getLength());
System.out.println("Received Packet Length: " + receivedPacket.getLength() + "/" + receivedPacket.getData().length);
buffer.order(ByteOrder.LITTLE_ENDIAN);
buffer.put(receivedPacket.getData(),0,receivedPacket.getLength());
buffer.position(0);
if(localPort == SRPDefinitions.HB_PORT){
System.out.println("HB Message Received from " + strIPAddress + "!");
SRPHeartBeatMessage message = new SRPHeartBeatMessage(buffer);
//message.print();
}
if(localPort == SRPDefinitions.ALARM_PORT){
System.out.println("ALARM Message Received from " + strIPAddress + "!");
SRPAlarmMessage message = new SRPAlarmMessage(buffer);
message.print();
}
if(localPort == SRPDefinitions.TRACK_PORT){
System.out.println("TRACK Message Received from " + strIPAddress + "!");
}
}
netstat
的输出(正确列出监听 UDP 套接字的选项取决于你的操作系统)。 - chrylis -cautiouslyoptimistic-