Search code examples
javaconcurrencydistributed-computing

Java Concurrent Socket Programming


Below is my code for a simple Concurrent Server. Whenever I run multiple clients, the server only prints out the input of the first client. I'm not sure what I've done wrong. Any help would be appreciated.

public static void main(String[] args) {
    try {
        ServerSocket serverSocket = new ServerSocket(8001);
        while (true){
            Socket clientSocket = serverSocket.accept();
            System.out.println(clientSocket);
            ConcurrentServer client = new ConcurrentServer(clientSocket);
            client.start();
        }
    } catch (IOException i){}
}

public void run(){
    try {
        inputStream = new BufferedReader(new InputStreamReader(concurrentSocket.getInputStream()));
        outputStream = new PrintWriter(new OutputStreamWriter(concurrentSocket.getOutputStream()));

        String testString = inputStream.readLine();
        System.out.println(testString);


    } catch (IOException i){}
}

Solution

  • This code might help you to understand how to run multiple clients concurrently. :)

    What this code does? TCP Client sends a string to the server and TCP server sends back the string in UPPERCASE format & the server can do this concurrently with multiple connections.

    I have included 3 files for the server and one more for testing the server with multiple clients(ClientTest.java)

    Main.java

    import java.io.IOException;
    
    public class Main {
    
        public static void main(String[] args) {
            try {
                new Server(3000).start();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    Server.java

    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.logging.Logger;
    
    public class Server {
    
        private ServerSocket sSocket;
        private boolean run;
        private int port;
    
        public Server(int port) throws IOException {
            this.port = port;
            this.sSocket = new ServerSocket(this.port);
        }
    
        public void start() {
    
            this.run = true;
            Logger.getLogger(getClass().getName()).info("Server is listening on port: " + port);
    
            try {
                while (run) {
                    Socket cs = sSocket.accept();
                    Logger.getLogger(getClass().getName())
                            .info("New Client Connected! " + cs.getPort());
                    new Thread(new Client(cs)).start(); // Put to a new thread.
                }
            } catch (IOException e) {
                Logger.getLogger(getClass().getName()).severe(e.getMessage());
            }
        }
    
        public void stop() {
            this.run = false;
        }
    }
    

    Client.java (Client Process on server)

    import java.io.*;
    import java.net.Socket;
    import java.util.logging.Logger;
    
    public class Client implements Runnable {
    
        private Socket clientSocket;
    
        private DataOutputStream out; // write for the client
        private BufferedReader in; // read from the client
    
        public Client(Socket clientSocket) {
            this.clientSocket = clientSocket;
        }
    
        @Override
        public void run() {
            // Do client process
            outToClient(inFromClient().toUpperCase());
            closeConnection();
        }
    
        private String inFromClient() {
    
            String messageFromClient = "";
    
            /*
             *  Do not use try with resources because once -
             *  - it exits the block it will close your client socket too.
             */
            try {
                in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                messageFromClient = in.readLine();
            } catch (IOException e) {
                Logger.getLogger(getClass().getName()).severe("InFromClientErr - " + e.getMessage());
            }
    
            return messageFromClient.trim().equals("") ? "No Inputs given!" : messageFromClient;
        }
    
        private void outToClient(String message) {
            try {
                out = new DataOutputStream(clientSocket.getOutputStream());
                out.writeBytes(message);
            } catch (IOException e) {
                Logger.getLogger(getClass().getName()).severe("OutToClientErr - " + e.getMessage());
            }
        }
    
        private void closeConnection() {
            try {
                in.close();
                out.close();
                clientSocket.close();
            } catch (NullPointerException | IOException e) {
                Logger.getLogger(getClass().getName()).severe(e.getMessage());
            }
        }
    }
    

    ClientTest.java (For Testing clients)

    import java.io.*;
    import java.net.Socket;
    import java.util.Scanner;
    
    public class ClientTest {
    
        public static void main(String[] args) {
    
            Socket clientSocket;
    
            try {
                clientSocket = new Socket("localhost", 3000);
    
                DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
                BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    
                outToServer.writeBytes(new Scanner(System.in).nextLine() + '\n'); // Get user input and send.
                System.out.println(inFromServer.readLine()); // Print the server response.
    
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }