是否必须在RXTX中进行常规轮询?

时间:2009-09-08 04:19:28

标签: java windows serial-port rxtx

在尝试找出this problem时(任何帮助都很受欢迎),我在使用PortMon监视其活动的同时运行RXTX并注意到RXTX会不断检查数据是否可用,即使是Java客户端也是如此仅通过SerialPortEventListener从gnu.io.SerialPort对象读取。

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

另一方面,超级终端不进行轮询(并且没有问题)。它是否可以访问一些隐藏的Windows系统调用,让它执行此操作?

1 个答案:

答案 0 :(得分:4)

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

Rxtx内部有点不同/怪异但有一些错误。 简短版本,这是它应该如何工作:你有两个参数:超时和阈值。根据源代码设置,超时为0(无),阈值为1(返回前至少需要1个字节),应该通过InputStream定义阻塞读取。

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

/ * TESTING 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;
    }
    
  3. 然后你执行:read(in)而不是in.read()

    我实际上在2年前写过a blog entry about this所以我不会忘记。