【发布时间】: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