0


I write UDP server and client in Java to send message from client to server. In my case, every message from client will be stored in database. I tried to make a multithread UDP server using fixed thread pool. But now I encountered a problem, I found out that one message from client can be processed by more than one thread. My server look like this :

    DatagramSocket serverSocket = new DatagramSocket(9876);
    Map<String, Integer> retryMap = new ConcurrentHashMap<>();
    byte[] receiveData = new byte[1024];

    ExecutorService executor = Executors.newFixedThreadPool(2);

    while(true){
        DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
        serverSocket.receive(receivePacket);
        executor.execute(new ThreadServer(receivePacket, retryMap));
    }

ThreadServer class :

public void run(){
  String temp = new String(packet.getData(), 0, packet.getLength()); 
  long threadId = Thread.currentThread().getId();
  System.out.println("Thread Id = "+threadId+" Message = "+temp);
  // insert message to db
}

And my client look like this :

public class UDPClient1{
String message;
public UDPClient1(String message){
    this.message = message;
    try{
        byte[] sendData;

        DatagramSocket clientSocket = new DatagramSocket();
        InetAddress IPAddress = InetAddress.getByName("localhost");

        sendData = message.getBytes("UTF-8");

        DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 9876);
        clientSocket.send(sendPacket);

        clientSocket.close();
    }catch(Exception e){
        e.printStackTrace();
    }
}

public static void main(String args[]) throws InterruptedException{
    int i = 0;
    while(i < 1000){
        new UDPClient1("T000"+i+"_"+i);
        System.out.println(i);
        i++;
        Thread.sleep(2);
    }
}}

The output from the server show that sometimes one message from client will be processed by 2 thread or more.

Thread Id = 18 Routing Id = T000975 09:54:11,759 ERROR LogRoutingFileDaoImpl:59 - AMS - Error insert to database org.springframework.dao.DuplicateKeyException: PreparedStatementCallback; SQL [INSERT INTO LOG_ROUTING_FILE (ID_ROUTING_FILE, FILE_NM , PATH, TYPES, PROTOCOL, SOURCE_NM, TARGET_NM) VALUES (?,?,?,?,?,?,?)]; ERROR: duplicate key value violates unique constraint "log_routing_file_id_routing_file_key"; nested exception is org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "log_routing_file_id_routing_file_key" 
Thread Id = 9 Routing Id = T000975 09:54:11,759 ERROR LogRoutingFileDaoImpl:59 - AMS - Error insert to database org.springframework.dao.DuplicateKeyException: PreparedStatementCallback; SQL [INSERT INTO LOG_ROUTING_FILE (ID_ROUTING_FILE, FILE_NM , PATH, TYPES, PROTOCOL, SOURCE_NM, TARGET_NM) VALUES (?,?,?,?,?,?,?)]; ERROR: duplicate key value violates unique constraint "log_routing_file_id_routing_file_key"; nested exception is org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "log_routing_file_id_routing_file_key"

The message T000975 is processed by thread 9 and 18.. Can anyone help me to solve this? :)

1 Answer 1

2
byte[] receiveData = new byte[1024];

You're sharing the same byte array among all the DatagramPackets. Move this line inside the receive loop.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, it worked :) can you please kindly explain what is the difference between placing the recevieData declaration outside the loop and inside the loop?
I've answered that. 'You're sharing the same byte array among all the DatagramPackets.' If you move it inside the loop, there is a new byte array per packet.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.