I have to listen 3 different ports for UDP in my Java project. I implemented my system as follows:
I have a UDPMessageListener class which implements Runnable. I want to create 3 threads running as this object.
I have an interface called " UDPPacketProcessor " which has a single onPacketReceived method.
Every UDPMessageListener has a UDPPacketProcessor instance, and directs the UDP packet to the object registered as its UDPPacketProcessor.
And I have a DatabaseProc Class which needs to serve to the messages coming from 3 different UDP ports. DatabaseProc implements UDPPacketProcessor to register itself to those 3 UDPMessageListener classes.
In theory, according my Java knowledge there cannot be any problem, 3 Runnable threads listens to 3 ports, and on packet received, calls a method of my main singleton object's method. However, when I run the program, only one of the ports is listened. I can only the HBMessageListener works correctly, the others do not respond. When I bypass the HBMessageListener (comment out the line I run it) I can now see that only AlarmMessageListener works. Where am I wrong?
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 + "!");
}
}
The issue is in DatabaseProc
class. Change runListeners
to as following.
private void runListeners(){
new Thread(HBMessageListener).start();
new Thread(AlarmMessageListener).start();
new Thread(TrackMessageListener).start();
}
EDIT
Explanation is when UDPMessageListener.run()
is directly called, It is not creating a new Thread and executing asynchronously. With your code as it is the execution will never come out of HBMessageListener.run()
method as it is in a infinite loop. You need to parallelize the Listeners so that all can listen.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.