【问题标题】:BufferedReader drops lines [closed]BufferedReader 掉线[关闭]
【发布时间】:2013-06-17 11:00:22
【问题描述】:

我在与我的主应用程序不同的线程中写信给ServerSocket

    BlockingQueue<String> queue = new Queue<>();

    // THREAD
ServerSocket server = new ServerSocket(2222);
Socket socket = server.accept();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),"UTF-8"));

while (true) {
    String line = queue.take();

    if (line != null) {
        try {
            logger.debug("Sending command " + line);
            writer.write(line + "\n");
            writer.flush();
        } catch (IOException e) {
            logger.error("IO error", e);
            e.printStackTrace();
        }
    }

}

queue 从外部填充的位置。

发送内容正常,我可以通过在端口 2222 上使用 telnet 并读取调试记录器输出来验证这一点。

在 android 上,我通过以下代码在端口 2222 上读取数据:

Socket s = new Socket("host",2222);
BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream(),"UTF-8"));
while((line = reader.readLine()) != null) {
    Log.d("PAINT","RECEIVED::" + line);

    // create Message, Bundle, send Message to handler.

}

但是,我发送的每几条消息中就有一条(例如十分之一)没有被安卓手机接收。有关如何发生这种情况以及如何解决此问题的任何提示?

【问题讨论】:

  • 您知道Queue&lt;T&gt; 不是线程安全的吗?您似乎在使用它,就好像您期望的那样。
  • 好点,但似乎我们应该解决这个问题,但这不是问题;每次 Android 线程不注册读取时,我都会记录写入。
  • 使用java.util.concurrent 中的集合之一。如果您要使用 BlockingQueue 之类的 LinkedBlockingQueue,那么您可以删除您似乎正在使用的可怕的忙等待反模式。
  • 另请注意,您在每个平台上都使用默认字符编码,这绝不是一个好主意。
  • 作为调试的线索,您可以在发送的每条消息中添加一个计数器,以便确定缺少什么。例如:counter++; writer.write(String.format("%3d: %s\n", counter, line)); writer.flush();有了这个,您可能会知道真正丢失了什么。

标签: java android sockets java-io


【解决方案1】:

事实证明,我们的代码存在许多问题。原来有两个线程写入缓冲区,因为 android 应用程序连接了两次。只有一个正在写入正确的套接字。队列上缺乏同步使得哪个线程正在消费事件变得不可预测,因此在 ja_mesa 提示对调试日志编号之前很难注意到。

原来我们不得不在 inputthread 死掉后终止 outputwriter 线程。

【讨论】:

    猜你喜欢
    • 2012-01-02
    • 2012-08-25
    • 1970-01-01
    • 2019-01-27
    • 1970-01-01
    • 2021-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多