Troubleshooting Data Handling Issues in a Multithreaded Server Class for Multiple Client Connections

Hello, I hope you’re doing well. I did a server class to handle multiple client connections simultaneously. Each client sends a fixed amount of data that I want to store and then process into a CSV file. Here is the complete code for the server class:

import java.io.*;
import java.net.*;
import java.util.concurrent.*;

class ServerHandler implements Runnable {
    private ServerSocket server;
    private boolean serverRunning = true;
    private String receivedMessage = null;
    private int port;
    private boolean isConfigserver;
     private ExecutorService clientThreadPool;
    
      public ServerHandler(int port, boolean isConfigserver) {
        this.port = port;
        this.isConfigserver=isConfigserver;
        this.clientThreadPool = Executors.newFixedThreadPool(10);
    }
    @Override
    public void run() {
        try {
            // Create a server socket to listen on port 1234
            server = new ServerSocket(this.port);
            println("Server is running on port : ");
            print(this.port);
            
            while (serverRunning) {
                try {     
                      Socket client = server.accept(); // Accept incoming connections
                    System.out.println("Client connected: " + client.getInetAddress());
                    if(!isConfigserver) {
                             // Handle each client connection in a separate thread
                    ClientHandler clientHandler = new ClientHandler(client, selectedMode, Nombre_mesures);
                    clientThreadPool.submit(clientHandler);
                    }
                    else {
                       BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
                       String receivedData = reader.readLine();
                              if (receivedData != null) {
                                  receivedData = receivedData.trim();
                                  println("Received from Arduino about config: " + receivedData);
                                  if(receivedData.equals("OK")) {
                                    isReady=true;
                                    println("we are ready to go");
                                  }
                              }
                              client.close();
                               println("Client connection closed after configuration");
                    }
                 
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } 
    }
    public void stopServer() {
    serverRunning = false;
    if (server != null && !server.isClosed()) {
        try {
            server.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
     clientThreadPool.shutdown();
}
private class ClientHandler implements Runnable {
        private Socket client;
        private String selectedMode;
        private int Nombre_mesures;
        private int counter_requete = 0;

        public ClientHandler(Socket client, String selectedMode, int Nombre_mesures) {
            this.client = client;
            this.selectedMode = selectedMode;
            this.Nombre_mesures = Nombre_mesures;
        }

        @Override
        public void run() {
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()))) {
  
                    while (counter_requete < Nombre_mesures) {
                        String receivedData = reader.readLine();
                        if (receivedData != null) {
                            receivedData = receivedData.trim();
                            System.out.println("Received from Arduino: " + receivedData);
                            extractAndWriteData(receivedData, selectedMode,counter_requete);
                            counter_requete++;
                            println("voici le counter en cours : " + counter_requete);
                        }
                    }
                       counter_requete = 0;
                 
    
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    client.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                System.out.println("Client connection closed");
            }
        }



}
}

I implemented multithreading to manage multiple connections simultaneously. However, I’m currently facing an issue within the client class, specifically in the extractData function where the data processing occurs. The code for this function is as follows:

void extractAndWriteData(String msg, String selectedMode, int compteur) {
  // Split the message by commas to extract individual parts
  String[] parts = msg.split(",");
   String identifiant_GW=parts[0];
       switch (selectedMode) {
        case "Mode 1":
         
            break;
        case "Mode 2":
            // Code for Mode 2
           snrPart = parts[1];
           rssiPart = parts[2];
           timePart=parts[3];
          
          
           timePart= trim(timePart); // Trim whitespace
           temps =float(timePart)/1000;
           
           
           println(identifiant_GW,rssiPart,snrPart,timePart);
        
            try {
     int index_excel=Integer.parseInt(identifiant_GW);
    int index = gatewayList.indexOf(index_excel);
    if (index == -1) {
        println("Invalid index_excel: " + index_excel);
        return;
    }
    if (outputWriters[index] == null) {
        println("Output writer not initialized for index: " + index);
        return;
    }

    // Log before writing to the file
    println("Writing to file for index: " + index);
    outputWriters[index].println(identifiant_GW + ";" + rssiPart + ";" + snrPart + ";" + timePart + ";" + x_position + ";" + y_position + ";" + z_position);
    println("Successfully wrote to file for index: " + index);
} catch (Exception e) {
    println("Exception while writing to file: " + e.getMessage());
    e.printStackTrace();
}
           
  
          

break
        default:
            // Default code if SelectedMode does not match any case
            break;
    }
      
      if (compteur >= Nombre_mesures) {
         outputWriters[gatewayList.indexOf(Integer.parseInt(identifiant_GW))].flush();
         outputWriters[gatewayList.indexOf(Integer.parseInt(identifiant_GW))].close();
        println("File closed after reaching the required number of measurements for GW : "+ identifiant_GW);
     } 
}

my problem is once the client reach to step were he needs to write the current measure into the csv file he disconnect directly, however if i comment that line ( the outputwriter line) , i can print all data in terminal, so i m wondering what s the issue, is it a synchronisation problem ?
PS : the excel file are created at the very beginning of the sketch and the code was functioning well before multithreading ( when i only had one client and not multiple ones), can you suggest to me a solution ?

Hi @hakim,

Please check here.

Cheers
— mnse

1 Like