首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >BufferedReader永不就绪(Java中的套接字编程)

BufferedReader永不就绪(Java中的套接字编程)
EN

Stack Overflow用户
提问于 2011-05-19 18:42:22
回答 4查看 9.7K关注 0票数 7

我已经像这样声明了socket:

代码语言:javascript
运行
复制
serverAddr = InetAddress.getByName(this.ip);
socket = new Socket(serverAddr, port);
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);

然而,下面的方法不起作用。in.ready()总是返回false,如果删除,程序将在String message = in.readLine();处冻结

代码语言:javascript
运行
复制
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();
        }

    }

我该怎么解决这个问题呢?

编辑:

下面是在我的服务器类中发送消息的方式: out.println( message );out.flush();每当我在message中放入一些东西时,这都会在一个循环中发生。out在此循环后关闭。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-05-19 19:09:21

我脑海中浮现出三件事:

  • 您在每次receive调用中都会重新打开输入流,并将其包装到BufferedReader中。这可能会将多个行读取到缓冲区中,并且在完成(关闭它)之后,剩余的缓冲字节将不再可用于后续的receive调用
  • 您是否考虑过使用自己的线程来读取服务器消息?在那里,如果它被阻塞了,也不会有什么坏处,因为我在写入数据后关闭套接字的一侧,然后立即关闭它的时候,我遇到了一些问题。
  • 。有时,尽管进行了flush()close()调用,但另一端并未接收到所有数据。也许在你的情况下这也是一个问题

编辑:

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

代码语言:javascript
运行
复制
if (in.ready()) {
    String message;
    while ((message = in.readLine()) != null) {
        // ...
    }
 }

但要小心,因为最后一行可能是部分读取的消息(例如,缓冲了3和1/2消息)。如果这是一个问题,您可以逐个读取消息以确定行何时结束,并使用PushbackReader来放回不完整的消息。

票数 1
EN

Stack Overflow用户

发布于 2011-05-19 18:58:50

你不应该像这样使用ready()javadoc这样说:

“返回:如果下一次read()保证不阻塞输入,则返回True,否则返回false。请注意,返回false并不保证下一次read将阻塞。”

您的代码隐含地假设ready() -> false意味着下一个read将阻塞。实际上,这意味着下一个read可能会阻塞,也可能不会阻塞。

正如@EJP所说...只需执行read调用。

我能做些什么来防止阻塞呢?如果被阻止,客户端将无法发送任何内容

如果读操作中的阻塞对您的应用程序是一个问题,请使用单独的线程进行读取,或者更改您的代码以使用NIO通道选择器。

票数 4
EN

Stack Overflow用户

发布于 2011-05-19 18:45:00

只需删除in.ready()测试。这对你没有帮助。readLine()将被阻塞,直到有数据可用。如果还没有数据到达,您还计划做什么?

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6057399

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档