6

在试图解决这个问题时(感谢任何帮助),我在使用PortMon监视其活动的同时运行 RXTX,并注意到 RXTX 不断检查数据是否可用,即使 Java 客户端仅从 gnu.io.SerialPort 对象读取通过 SerialPortEventListener。

为什么是这样?是 RXTX 人的糟糕实现选择,Sun 糟糕的 API 选择(因为 RXTX 遵循 javax.comm API),还是本地代码支持的运行 Java 的限制?

另一方面,超级终端不进行轮询(并且可以正常工作)。它是否可以访问一些隐藏的 Windows 系统调用,让它这样做?

4

1 回答 1

4

不,这不是由于 javax.xomm API。顺便说一句,Rxtx 可以通过该 API 使用,也可以不使用。

Rxtx 内部虽然有点不同/奇怪,但有一些错误。简短版本,它应该是这样工作的:你有两个参数可以使用:超时和阈值。根据源代码将超时设置为 0(无)和阈值设置为 1(在返回之前至少需要 1 个字节)应该给我们正常,由 InputStream 定义,阻塞读取。

问题是即使这样设置,当前稳定版本(2.1.7r2)中也存在错误。阈值参数始终设置为 0!从源代码:

/* 测试 ttyset.c_cc[ VMIN ] = 阈值;*/ ttyset.c_cc[ VMIN ] = 0;

令人困惑的是,2004 年也是如此,并在邮件列表中报告并修复了,但它要么没有真正修复,要么又回来了(回归)。实际上有一个新的错误报告,由于某种原因我一开始找不到。我最终发现它会抛出预发布包源代码,并找到了一个未发布的更改日志(在最后一个稳定版本之后,网页不显示更改日志,但它在 CVS 中可用)。

解决方案

  1. 它固定在 HEAD 上,因此您可以使用最新的预发布版本(2.2 系列)或从 CVS 编译它。
  2. 按照以下方式制作一个丑陋的解决方法:

    int read(InputStream in) throws IOException {
      int b; 
      while ((b=in.read()) == -1) { 
        try { Thread.sleep(10); } catch (InterruptedException e) { }
      }
      return b;
    }
    

然后你做:read(in)而不是in.read().

实际上,我在2 年前写了一篇关于这个的博客文章,所以我不会忘记。

于 2012-03-04T00:36:27.720 回答