-1

In my simple Java Client-Server program, when sending a message to the server and reading it there, readInt() reads indefinitely, making the program stick there.

I made sure I was only sending and receiving an int, nothing else, as you can tell by the code (I also tried with and without appending \n to the message sent to see if it would end):

Relevant Client Code

Socket server = new Socket("127.0.0.1", 2424);
DataOutputStream outputStream = new DataOutputStream(server.getOutputStream());
DataInputStream inputStream = new DataInputStream(server.getInputStream());
outputStream.writeInt(Protocol.Message.HANDSHAKE);
outputStream.write('\n'); // I tried with and without this
outputStream.flush();

Relevant Server Code

ServerSocket socket = new ServerSocket(2424);
System.out.println("Listening on port 2424");

while (connected) {
    Socket client = socket.accept();
    System.out.println("SERVER: Going to read a message"); // This shows
    int messageType = (new DataInputStream(client.getInputStream())).readInt();
    System.out.println("SERVER: Received a message (" + messageType + ")"); // This does not
    commands.execute(messageType);
}

The message that should be printed after readInt() is never seen. I thought it would since I was only sending an int and receiving an int (4 bytes), it's not like I was sending more data than expected.

How should I go about making the readInt() end? Do I have to send a null byte or something else?

EDIT: Actual Server code (using Threads).

ServerSocket socket = new ServerSocket(2424);
System.out.println("Listening on port 2424");

while (connected) {
    Socket client = socket.accept();
    Worker worker = new Worker(client);
    worker.start();
}

Worker Thread

public class Worker extends Thread {
    private final Socket client;
    private final Commands commands;

    private final DataOutputStream outputStream;
    private final DataInputStream inputStream;

    public Worker(Socket client) throws IOException {
        System.out.println("SERVER: Handling client message");
        this.client = client;

        outputStream = new DataOutputStream(client.getOutputStream());
        inputStream = new DataInputStream(client.getInputStream());

        commands = new Commands();
        commands.addCommand(Protocol.Message.HANDSHAKE, new HandshakeCommand());
        //commands.addCommand(Protocol.Message.RECEIVE_FILE, new ReceiveFileCommand());
    }

    @Override
    public void run() {
        System.out.println("SERVER: Running thread for client message");
        try {
            int messageType = inputStream.readInt();

            System.out.println("SERVER: Received a message (ID " + messageType + ")");
            commands.execute(messageType);
        } catch (IOException | UnknownCommandException ex) {
            System.out.println(ex);
        }
    }
}
Derrick C.
  • 21
  • 2
  • 4
  • I just tested your code and it works as expected on my machine. I used `outputStream.writeInt(42);` and the server received it with `SERVER: Received a message (42)`! So either you don't even start your server and client properly or there is some other network problem with the port or what have you tried? – xander Dec 13 '17 at 11:49
  • The Server code actually delegates each `socket.accept()` into a new thread, but I don't think that would affect it in any way? I'll give it another go and come back with results. Also any explanation about the `\n`? Do I have to include that in the message or not? – Derrick C. Dec 13 '17 at 12:15
  • You don't need to send the `\n` or anything else, the `DataInputStream.readInt()` on the server side will block the thread until 4 bytes have arrived and then convert it to an 4-byte int. So most likely you never send 4 bytes to the server socket. If you use extra thread maybe provide a minimal version that does not work, because the code from your question has no errors in it, you can try it yourself if that code works for you. – xander Dec 13 '17 at 12:39
  • I have updated the main post with the actual code. – Derrick C. Dec 13 '17 at 13:33
  • I still can't reproduce the error, with your actual server code it works fine. I had to remove your command stuff because you didn't provide that code, but that should not have any effects in the socket connection. So the question is how are you actually running your server and client code? They have to run in parallel obviously. Start the server so it's listening and then start another JVM with the client socket code!? – xander Dec 13 '17 at 13:47
  • Yes, in Netbeans I run the server first and while it is running, the client which sends a message. The client sends an integer and the server does receive the message from the client (since it shows `SERVER: Handling client message` and `SERVER: Running thread for client message` in console). But it does not show the `SERVER: Received a message` that should be printed after `readInt()`. https://i.imgur.com/y0xd29S.png – Derrick C. Dec 13 '17 at 14:02
  • `ServerSocket` doesn't read anything. It only accepts connections. – user207421 Dec 13 '17 at 14:57

1 Answers1

0

The reason it was never reading is because nothing was being sent, as xander said. And it was my fault I didn't include the actual client code, just the server code and a minimized version of the client code.

I was trying to send the message after the while() loop in the client (it also waits for messages from the server).

The solution was to delegate the the client's listening part into another thread so it didn't block the main thread that needed to send the message to the server.

Derrick C.
  • 21
  • 2
  • 4