user83676
user83676

Reputation: 379

Java Sockets - Running the same client multiple times in parallel.

(Disclaimer that some of this code will be similar to online tutorials)


I think I've made it so that my server can handle multiple requests at once using threads, but I'm not entirely sure. And on top of that I don't know how I would actually send multiple requests at once.

My goal is to run my client code multiple times in parallel to see what happens if multiple clients connect to the server at the same time.

Client code (in separate project package):

        Client clientSocket = new Client(9990,"localhost");
        Socket socket = new Socket(clientSocket.host,clientSocket.portNumber);
        clientSocket.performTask(socket);

("performTask(socket)" sends data to the server to perform a task)

Server code (separate project package from client code):

    Server server = new Server(9990);
    int clientNumber = 0;
    ServerSocket socket = new ServerSocket(server.portNumber);
    try { 
        while (true) {
            new ServerHandler(socket.accept(),clientNumber).go();
            clientNumber++;
        }
    }
    finally {
        socket.close();
        }
}

ServerHandler class (same project package as server code):

public class ServerHandler extends Thread {
    private static Socket socket;
    private static int clientNumber;

    public ServerHandler(Socket socket, int clientNumber) {
        ServerHandler.socket = socket;
        ServerHandler.clientNumber = clientNumber;
    }

    public void go() {
        while(true) {
        try {
            //do calculation, do server tasks, etc.
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        }
    }

So when the client connects to the server, the server implements the ServerHandler class to do the necessary calculations: the idea in doing that was so that multiple clients could connect all at the same time.

So my question is then in two parts:

(1) Have I set up my programs to allow for multi-threading, or have I made a mistake somewhere along the way? (e.g. someone told me I needed to use "Runnable" somewhere to use multi-threading, and I notice I haven't)

(2) After fixing my code to allow for multi-threading, how would I actually use it to let me run my client code in parallel?

Upvotes: 0

Views: 4156

Answers (2)

Spray
Spray

Reputation: 21

You should use multithreading . You have to rename method to "run"/ and call that method using "start".Please change Server side code to

try { 
        while (true) {
            new ServerHandler(socket.accept(),clientNumber).start();
            clientNumber++;
        }
    }
    finally {
        socket.close();
        }

and client side

public class ServerHandler extends Thread {
    private static Socket socket;
    private static int clientNumber;

    public ServerHandler(Socket socket, int clientNumber) {
        ServerHandler.socket = socket;
        ServerHandler.clientNumber = clientNumber;
    }

    public void run() {
        while(true) {
        try {
            //do calculation, do server tasks, etc.
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        }

Upvotes: 0

Rishi
Rishi

Reputation: 220

Ok for starters, your ServerHandler extends the Thread class. Therefore to make it run as a seperate thread, always invoke by calling the start() method. You are calling you custom go method which will make the ServerHandler execute in the same thread as your infinite while loop. So it should be something like this ServerHandler(socket.accept(),clientNumber).start(). Also it is always better to implement Runnable because java does not support multiple inheritance via the "extends" concept. Therefore in the future if your ServerHandler needs to actually extend a custom class, it wont be able to since it already extends the Thread class. Its better to implement interfaces since there is no limit as to how many you can implement.

Hence implementing the Runnable interface is a good design choice. You can run your client code in parallel by making the client into a threaded model. Here is one such example of multiple client sockets connecting to the server in parallel

Server Code

public class WebServer {
    static int hitCount = 0;

    public static void main(String[] args) throws Exception {
        ServerSocket serverSocket = new ServerSocket(7777, 10000);
        while (true) {
            Socket defaultSocket = serverSocket.accept();
            new Thread(new ServerSlave(defaultSocket)).start();
            System.out.println("Size is :" + hitCount);
        }

    }
}

class ServerSlave implements Runnable {
    Socket clientSocket;

    public ServerSlave(Socket socket) {
        clientSocket = socket;
        WebServer.hitCount++;
    }

    public void run() {

        try {

            DataInputStream inputStream = new DataInputStream(clientSocket.getInputStream());
            DataOutputStream outputStream = new DataOutputStream(clientSocket.getOutputStream());
            System.out.println(inputStream.readUTF());
            outputStream.writeUTF("Thank you for contacting the web server");

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

Client Code :

public class Client {
    static int excepCount=0;
    public static void main(String[] args) throws Exception {
        for (int i = 0; i < 100; i++) {
            new Thread(new Worker("" + i)).start();
        }
        Thread.sleep(10000);
        System.out.println( Client.excepCount);
    }
}


class Worker implements Runnable {
    String clientName;

    public Worker(String name) {
        clientName = name;
    }

    public void run() {
        System.out.println("Process started for : " + clientName);
        Socket socket = null;
        try {
            socket = new Socket("127.0.0.1", 7777);
            DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
            outputStream.writeUTF("Hello socket. Client number " + clientName + "here");
            InputStream inFromServer = socket.getInputStream();
            DataInputStream in =
                    new DataInputStream(inFromServer);
            System.out.println("Server says " + in.readUTF());
            System.out.println("Closing socket");

        } catch (IOException e) {
            Client.excepCount++;
            e.printStackTrace();
        }finally{
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

Upvotes: 2

Related Questions