我正在与硬件设备建立客户端套接字连接。我正在向此连接发送命令以通过硬件进行处理。现在作为确认或回复,硬件发送响应。 应用程序会在10秒内定期向连接发送命令。
现在存在一个问题,即响应不会与应用程序发送的命令同步。我认为这是特定于硬件的,但令我惊讶的是,当我通过将putty连接到相同端口的相同硬件时看到响应时,我可以看到响应始终是同步的。这看起来像腻子,使用一些标准将请求映射到响应。
以下是我用来向硬件设备发送命令的编程步骤: -
Socket clientSocket = new Socket(<IPADDRESS>, 4001);
DataOutputStream outToServer = new DataOutputStream(
clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
while (true) {
try {
//Get command randomly from array enums for test
Random r = new Random();
Commands[] array = Commands.values();
String command = (String) array[r
.nextInt(Commands.values().length)].getCommand();
outToServer.writeBytes(command);
Thread.sleep(500);
while (!inFromServer.ready()) {
}
System.out.println("COMMAND "+command+", SERVER RESPONSE: "
+ inFromServer.readLine());
Thread.sleep(1500);
} catch (SocketTimeoutException se) {
//Handle Exception
} catch (SocketException se) {
//Handle Exception
}
任何人都可以建议如何将响应与请求同步作为putty这样的机制来实现?
答案 0 :(得分:1)
Putty对您的设备不再了解。问题出在您的代码中。摆脱ready()
测试和sleep()
。如果您可以确定设备发送了线路,请致电readLine()
,否则只需拨打InputStream.read().
答案 1 :(得分:1)
删除线程睡眠,并重写如下:
String line;
while ((line = inFromServer.readLine()) != null) {
System.out.println("COMMAND "+command+", SERVER RESPONSE: "
+ line);
}
如果设备发送的最后一条消息没有换行符\n
,则此代码仍然可以挂起。您的原始代码跳过了输入。
主要问题在于这一行:
while (!inFromServer.ready()) {
InputStreamReader#ready
只有在您有其他方式知道所有数据都已发送时才可以使用
判断此流是否已准备好进行读取。如果输入缓冲区不为空,或者可以从基础字节流中读取字节,则InputStreamReader就绪。
第一条消息将被读取,但会清空缓冲区,当第二条消息到达时,您的代码不再读取。你必须拥有与来自设备的消息一样多的循环,这至少是不切实际的。在这种情况下,它可能不会一直有效。
<强>返回:强>
包含行内容的字符串,不包括任何行终止字符;如果已到达流末尾,则 null
将读取已读取所有已发送的数据。但是如果你的设备没有发送新的行字符,那么这个方法永远不会读取该行 - 代码将挂起缓冲区中的所有数据。在这种情况下,您应该使用InputStreamReader#read
作为EJP建议:
<强>返回:强>
字符读取,或 -1,如果已到达流的末尾
我强烈建议您阅读IO Streams官方教程。
一般来说,等待不是由Thread.sleep
和busy waiting(执行空语句)完成的,例如:
while (true) {} /*or*/ while(true);
CPU正在执行空语句,它可能正在做一些其他工作,等待这一个完成。这是一种不好的做法。
如果您想了解有关如何实施等待的更多信息,建议您阅读official concurrency tutorial或this one,了解有关此问题的更广泛方法。