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

4
我正在本地测试套接字。我试图在一个程序中使用线程运行套接字和服务器。我的服务器是一个回显服务器,它会将收到的任何消息发送回去。我的问题是,当我启动客户端和服务器上的两个线程时,它们在读取输入流的部分都会“冻结”。在客户端发送消息的部分之前,它可以正常工作。之后,它就会停止工作,因为似乎客户端正在等待一条消息,而服务器也是如此,即使我已经通过写入输出流向服务器发送了一条消息。代码有什么问题呢?
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();
    }

}
2个回答

6
您正在编写一个字符串,但是该字符串末尾缺少换行符。
            String inputText = input.readLine();
            writer.write(inputText);
            System.out.println("Client 2");

inputText字符串中不包含您输入的行尾符号。您将其原样写入服务器。但是,服务器会尝试读取一行:

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

因此,它将一直等待,直到客户端发送一个换行符。但是此时客户端正在等待服务器的答复,现在它们被死锁了。

因此,您应该在客户端和服务器的回显中都添加 writer.newLine(),以解决相同的问题。建议在每次写入后,在服务器和客户端上使用 writer.flush()。否则,它可能会等到缓冲区满之前才实际写入,从而导致相同的死锁情况。


现在它可以工作了。非常感谢!我从来没有想过问题竟然是由于缺少换行符而引起的。 - Lexicographical

4
BufferedReaderreadLine 方法需要一个新的行结束符才能返回值(除非到达了流的末尾),然后返回该行 不包括 此字符。因此客户端:
  1. 将一行内容读入变量 inputText
  2. 客户端将 inputText 写入 OutputStream
  3. 服务器接收到数据,但等待直到接收到一个新的行(实际上并没有等到)。

如果您希望使用换行符作为通信分隔符,请将其附加到发送的数据的末尾。

writer.write(inputText + "\n");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接