【问题标题】:Java BufferedInputStream read() does not receive data after not reading from Stream for some timeJava BufferedInputStream read() 在一段时间没有从 Stream 读取后没有接收到数据
【发布时间】:2018-01-02 14:17:18
【问题描述】:

我编写了一个应用程序来监听来自机器人的状态消息。我与机器人有一个开放的 Socket 连接。机器人不断发送我阅读(和解析)的状态消息,以了解机器人何时完成当前任务。

 /**
 * Listens on the Socket for RobotStateMessage (RSM). A RSM has messagetype 16  at byte[4]. The constructor of the RobotStateMessage class
 * throws an exception when the message is found to be corrupt. If that happens the method waits for the next uncorrupted message.
 *
 * @param command the robot state message is added to the command
 * @throws IOException
 * @throws GeneralURMessage_Parse_Exception
 * @throws TimeExpired_Exception
 */
public void executeRobotStateCommand(RobotStateCommand command) throws IOException, RobotStateMessage.GeneralURMessage_Parse_Exception, TimeExpired_Exception {
    byte[] data = new byte[3000];
    boolean run = true;
    RobotStateMessage message = null;
    long momentToQuit = System.currentTimeMillis() + 5000;
    while (run) {
        if (System.currentTimeMillis() > momentToQuit) {
            throw new TimeExpired_Exception(5000);
        }
        ur_in.read(data);
        int type = data[4];
        if (type == 16) {
            run = false;
            try {
                // contructor of RobotStateMessage parses the data
                message = new RobotStateMessage(data);
            } catch (RobotStateMessage.CorruptRobotStateMessage_Exception e) {
                // the message received form ur was corrupted , ignore and wait for next message
                run = true;
            }
        }

    }
    command.robotStateMessage = message;

}

当我停止从 BufferedInputStream ur_in 读取一段时间后,就会出现问题。任何超过大约一分钟的暂停,ur_in.read(data) 会在消耗完所有缓冲的旧数据后阻塞。

使用缓冲数据后,BufferedInputStream 上似乎没有新数据。使用第二个工具监听来自机器人的数据,我可以清楚地看到状态消息仍在广播中。

Socket 仍然存在,但 Inputstream 似乎已经“死亡”。我在套接字上设置了一个超时,以便 read() 不会永远阻塞,但这并不能解决我的问题,即我不再通过 BufferdInputStream 接收到数据。

唯一有帮助的是重新连接套接字,这对我的问题来说并不是一个令人满意的解决方案。

感谢任何帮助或建议如何解决此问题。如果您需要更多信息,请询问。

【问题讨论】:

  • "Inputstream 好像“死了”" 有它,还是只是在等待更多数据,因为流还没有关闭,因此它不知道是否会有更多数据终于来了?
  • 顺便说一句:ur_in.read(data); 不一定会填满data。您应该使用该方法调用的返回值来了解data 实际上有多少是新读取的数据。
  • @AndyTurner 数据应该以 25 Hz 625 字节的频率传输。因为我有 5 秒的超时,所以在超时之前应该有足够多的数据来读取。我也不在乎我读了多少,因为我的消息被 read() 识别的 endofLine 终止。缓冲区足够大,可以容纳最大的消息。这回答了你的问题吗?
  • 您的假设仍然无效。如果你想要四个字节,你必须循环直到你确定得到它们,或者使用DataInpurStream.readFully()。您还必须测试流的结束。这段代码不够用。
  • 您似乎也不知道Socket.setSoTimeout()。你不需要自己实现超时。

标签: java sockets inputstream


【解决方案1】:

我假设您正在使用 TCP。如果您不从缓冲区读取数据,您的套接字将通知机器人停止传输,直到缓冲区有能力接收更多数据。机器人软件最终必须处理无法写入的数据,并且可能会断开您的客户端。您不应该使用套接字缓冲区来存储数据,而是尽快将数据移动到另一个缓冲区。设置更大的接收缓冲区可能会有所帮助,但不是一个好主意。

【讨论】:

    猜你喜欢
    • 2011-02-23
    • 1970-01-01
    • 2011-11-08
    • 1970-01-01
    • 1970-01-01
    • 2022-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多