Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Socket Multithreading - Reading input stream pauses thread

I'm testing out sockets on my local machine. I'm trying to run both a socket and server in one program using threads. My server is an echo server so that it sends back whatever message it receives. My problem is that when I start both threads, on both the client and server, they 'freeze' when they reach the part where I read from the input stream. It works fine up to the part where the client sends the message. Afterwards, it simply stops as it appears that the client is waiting for a message and so is the server even if I already sent a message to the server via writing to the outputstream. What's wrong with the code?

Client.java

@Override
    public void run() {

        try {
            Socket socket = new Socket("localhost", 22600);

            BufferedReader br = new BufferedReader(new InputStreamReader(
                    socket.getInputStream()));
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
                    socket.getOutputStream()));
            BufferedReader input = new BufferedReader(new InputStreamReader(
                    System.in));
            System.out.println("Client 1");

            while (true) {

                System.out.print("\nEnter text : ");
                String inputText = input.readLine();
                writer.write(inputText);
                System.out.println("Client 2");

                System.out.println("Client 3");
                String s = br.readLine();
                System.out.println("CLIENT RECEIVED : " + s);

            }

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

    }

Server.java

@Override
public void run() {

    try {
        ServerSocket server = new ServerSocket(22600);
        Socket socket = server.accept();
        BufferedReader br = new BufferedReader(new InputStreamReader(
                socket.getInputStream()));
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
                socket.getOutputStream()));


        System.out.println("Server 1");
        while (true) {

            System.out.println("Server 2");
            String s = br.readLine();
            System.out.println("Server 3");
            if (s == null) {
                System.out.println("NULL SERVER SIDE ERROR");
                break;
            }

            writer.write("ECHO : " + s);
            System.out.println("SYSOUT ECHO " + s);

        }
        server.close();
    } catch (Exception e) {
        e.printStackTrace();
    }

}
like image 630
Lexicographical Avatar asked Dec 25 '22 19:12

Lexicographical


1 Answers

You are writing a string that does not have an end-of-line at its end.

            String inputText = input.readLine();
            writer.write(inputText);
            System.out.println("Client 2");

The inputText string does not include the end-of-line you typed. And you write it as-is to the server. However, the server tries to read a line:

        String s = br.readLine();
        System.out.println("Server 3");

So it will keep waiting until the client sends in a newline. But by now the client is waiting for an answer from the server, and now they are deadlocked.

So, you should add a writer.newLine() to the client, as well as the server's echo, which suffers from the same issue. It's also recommended, after each write, to use writer.flush(), on both server and client. Otherwise, it may wait until the buffer is full before actually writing, and the same deadlock will result.

like image 169
RealSkeptic Avatar answered Jan 08 '23 01:01

RealSkeptic