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

Nat*_*ons 6 java windows serial-port rxtx

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

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

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

Mat*_*der 4

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

\n\n

Rxtx 内部结构有点不同/奇怪,并且有一些错误。\n简短版本,这就是它应该工作的方式:您有两个参数可以使用:超时和阈值。根据源代码,将超时设置为 0(无),将阈值设置为 1(返回前至少需要 1 个字节)应该会为我们提供正常的(由 InputStream 定义的)阻塞读取。

\n\n

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

\n\n

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

\n\n

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

\n\n

解决方案

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

    \n\n
    int read(InputStream in) throws IOException {\n  int b; \n  while ((b=in.read()) == -1) { \n    try { Thread.sleep(10); } catch (InterruptedException e) { }\n  }\n  return b;\n}\n
    Run Code Online (Sandbox Code Playgroud)
  4. \n
\n\n

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

\n\n

事实上,我两年前写过一篇关于此的博客文章,所以我不会忘记。

\n