-1

I have a server-side socket running, with the aim for the socket to constantly accept new inputs from multiple different clients and the client can send an infinite number of requests. However, when I run the server and client, the server only seems to print only a single input from the client, even though the client is sending a new input every second.

What do I need to modify in order for the server to:

  1. serve multiple clients at once
  2. Receive and print out an infinite number of inputs from each client

Code:

The server socket thread:

public void run() {
    try {
        System.out.println("Binding socket..");
        ServerSocket serverSocket = new ServerSocket(portNumber);
// THE MAIN READING LOOP:
        while(true){
            Socket socket = serverSocket.accept();
            System.out.println("Socket is listening..");
            DataInputStream dis = new DataInputStream(socket.getInputStream());


//here, the code is meant to read the inputs made in the last 2 seconds as a single block (I'm making a game)

          

            if(tickHappened){
                DebugLogger.print("Tick happened.");
                String undividedInputs = dis.readUTF();
                String[] inputs = undividedInputs.split("/");
                DebugLogger.print("Messages:");
                for(int i =0; i < inputs.length;i++){
                    System.out.println(inputs[i]);
                }
                tickHappened = false;
            }
        }
    } catch (IOException e) {
        System.err.println(e);
        throw new RuntimeException(e);

    }
}

The client side, which sends inputs every second. The sendMessageToServer method is called:

package Graphics;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class ClientToServerCommunications {
    private static Socket s;

    static {
        try {
            s = new Socket("localhost",6666);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    ;
    private static DataOutputStream dout;

    static {
        try {
            dout = new DataOutputStream(s.getOutputStream());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    ;


    public static void sendMessageToServer(String message) throws InterruptedException {
        while (true) {
            Thread.sleep(1000);
            try {
                dout.writeUTF(message);
            } catch (Exception e) {
                System.out.println(e);
            }
        }
    }


}
Andrew Kor
  • 579
  • 7
  • 19

1 Answers1

0

Your server loop is reading only 1 request per client, and is servicing only 1 client at a time. serverSocket.accept() returns a new Socket for a newly connected client. You need to move the I/O logic for that Socket into a separate thread so that your loop can go back to accept() for the next client.

Try something more like this instead:

class ClientThread extends Thread {
    Socket client;

    ClientThread(Socket client) {
        this.client = client;
    }

    public void run() {
        try {
            DataInputStream dis = new DataInputStream(client.getInputStream());
            while (true) {
                String undividedInputs = dis.readUTF();
                String[] inputs = undividedInputs.split("/");
                DebugLogger.print("Messages:");
                for(int i = 0; i < inputs.length; i++){
                    System.out.println(inputs[i]);
                }
            }
        } catch (IOException e) {
            System.err.println(e);
        }
    }
}

public void run() {
    try {
        System.out.println("Binding socket..");
        ServerSocket serverSocket = new ServerSocket(portNumber);
        System.out.println("Socket is listening..");
        while (true) {
            Socket socket = serverSocket.accept();
            new ClientThread(socket).start();
        }
    } catch (IOException e) {
        System.err.println(e);
        throw new RuntimeException(e);
    }
}
user207421
  • 305,947
  • 44
  • 307
  • 483
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thanks, it now accepts multiple clients. So the game ticks every 2 seconds, and only then the server prints out all the inputs it received in the last 2 seconds. However it's currently printing 1 message per tick, even though on the client side, I am using a for loop and sending 10 messages in a row quickly. Any reason why it's stalling? – Andrew Kor Jun 21 '23 at 18:03
  • In my example, I took out the server ticking, as your client was sending 1 message per second, so `readUTF()` on the server will block waiting for each message to arrive, thus printing 1 message per second. If you want to add extra ticking back in on the serve side, you can certainly do so. – Remy Lebeau Jun 21 '23 at 23:24
  • Any way I can make `.readUTF()` non-blocking? I just want to consume all the inputs received by `DataInputStream` during that 2-second tick, not wait for the next input in the stream. – Andrew Kor Jun 23 '23 at 16:02
  • @AndrewKor https://stackoverflow.com/questions/3895461/ – Remy Lebeau Jun 23 '23 at 16:41
  • that guide is very helpful. Thanks – Andrew Kor Jun 24 '23 at 18:15