套接字多线程-读取输入流会使线程暂停

套接字多线程-读取输入流会使线程暂停

问题描述:

我正在测试本地计算机上的套接字.我正在尝试使用线程在一个程序中同时运行套接字和服务器.我的服务器是回显服务器,因此它会发回所收到的任何消息.我的问题是,当我同时在客户端和服务器上启动两个线程时,当它们到达我从输入流读取的部分时,它们将冻结".它可以很好地工作到客户端发送消息的那部分.然后,它停止了,因为似乎客户端正在等待消息,服务器也是如此,即使我已经通过写入输出流向服务器发送了消息.代码有什么问题?

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

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

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();
    }

}

您正在写的字符串的末尾没有行尾.

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");

inputText字符串不包括您键入的行尾.然后将其原样写入服务器.但是,服务器尝试读取一行:

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.

因此,您应该为客户端以及服务器的回显添加writer.newLine(),这也会遇到相同的问题.还建议在每次写入之后,在服务器和客户端上均使用writer.flush().否则,它可能要等到缓冲区已满后才能进行实际写入,并且会导致相同的死锁.

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.