0

我正在与硬件设备建立客户端套接字连接。我正在向此连接发送一个由硬件处理的命令。现在作为确认或回复,硬件发送响应。应用程序在 10 秒内定期向连接发送命令。

现在随机存在一个问题,即响应不会与应用程序发送的命令同步。我认为这是特定于硬件的,但令我惊讶的是,当我通过将腻子连接到同一端口的相同硬件来看到响应时,我可以看到响应总是同步的。这看起来像是使用某些标准将请求映射到响应的幕后操作。

以下是我用来向硬件设备发送命令的编程步骤:-

            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
        }

任何人都可以建议如何将响应与请求的同步实现为像腻子这样的机制?

4

2 回答 2

1

Putty 并不比你更了解你的设备。问题出在您的代码中。摆脱ready()测试和sleep(). 打电话readLine(),如果你能确定设备发送线路,否则就打电话InputStream.read().

于 2013-08-16T09:47:51.897 回答
1

删除线程睡眠,并像这样重写读取:

String line;
while ((line = inFromServer.readLine()) != null) {
    System.out.println("COMMAND "+command+", SERVER RESPONSE: "
                + line);
}

如果设备在没有换行符的情况下发送最后一条消息,此代码仍会挂起\n。您的原始代码跳过了输入。

主要问题在于这一行:

 while (!inFromServer.ready()) { 

InputStreamReader#ready只有当您有其他方式知道所有数据已发送时才可以使用:

告诉这个流是否准备好被读取。如果 InputStreamReader 的输入缓冲区不为空,或者可以从底层字节流中读取字节,则 InputStreamReader 已准备就绪。

第一条消息将被读取,但这会清空缓冲区,当第二条消息到达时,您的代码将不再读取。您必须拥有与来自设备的消息一样多的循环,至少这是不切实际的。在那种情况下,它可能不会一直有效。

另一方面BufferedReader#readLine

回报:

包含行内容的字符串,不包括任何行终止字符,如果已到达流的末尾,则为 null

将读取直到发送的所有数据都被读取。但是,如果您的设备没有发送换行符,那么此方法将永远不会读取该行 - 代码将与缓冲区中的所有数据一起挂起。在这种情况下,您应该InputStreamReader#read按照 EJP 的建议使用:

回报:

读取的字符,如果已到达流的末尾,则为 -1

我强烈建议你阅读IO Streams官方教程。

一般来说,等待不是通过忙等待(执行空语句)来完成的,例如Thread.sleep

while (true) {}  /*or*/ while(true);

CPU 正在执行空语句,它可能在等待该语句完成时正在做一些其他工作。这是一种不好的做法。

如果您想了解有关如何实现等待的更多信息,我建议您阅读官方并发教程这篇文章以获得更广泛的方法。

于 2013-08-16T09:48:10.850 回答