BufferedReader从未准备好(用Java编写Socket编程)

Sad*_*ace 6 java sockets bufferedreader ready

我有套接字已经声明套接字像这样:

serverAddr = InetAddress.getByName(this.ip);
socket = new Socket(serverAddr, port);
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
Run Code Online (Sandbox Code Playgroud)

但是,以下不起作用.in.ready()总是返回false,如果删除,程序将冻结String message = in.readLine();

private void receive() {
        try {
            InputStreamReader isr = new InputStreamReader(socket.getInputStream());
            System.out.println(isr.getEncoding());
            BufferedReader in = new BufferedReader(isr);
            if (in.ready()) {
                String message = in.readLine();
                if (message != null) {
                    if (listener != null) {
                        listener.receiveMessage(ip, message);
                    } else {
                        print("Client recieved: " + message);//
                    }
                }
            }
            in.close();
        } catch (Exception e) {
            print("Error with input stream: " + e);
            disconnect();
        }

    }
Run Code Online (Sandbox Code Playgroud)

我怎么能解决这个问题?

编辑:

这就是我的服务器类中的发送方式:out.println(message); 了out.flush(); 每当我在消息中放入某些内容时,就会发生这种情况.在此循环后关闭.

kin*_*nak 1

我想到了三件事:

  • 您在每次调用中重新打开输入流receive,并将其包装到BufferedReader. 这可能会在缓冲区中读取不止一行,并且在完成(关闭它)后,剩余的缓冲字节将不再可用于后续操作receive调用
  • 您是否考虑过使用自己的线程来读取服务器消息?在那里,即使被阻挡也不会造成伤害
  • 我在写入数据后关闭套接字的一侧并立即关闭它时遇到了一些问题。flush()有时,尽管有呼叫,但对方并未收到所有数据close()。也许这也是您的情况的一个问题

编辑:
仅将in引用保留在方法之外receive并不能完全解决您的问题。您应该使用 while 循环来读取所有缓冲的消息并为每个人调用侦听器,例如:

if (in.ready()) {
    String message;
    while ((message = in.readLine()) != null) {
        // ...
    }
 }
Run Code Online (Sandbox Code Playgroud)

但请注意,最后一行可能是部分读取的消息(例如,缓冲了 3 条和 1/2 条消息)。如果这是一个问题,您可以逐个字符地读取消息来确定行何时结束,并使用 aPushbackReader来放回不完整的消息。