RXTX 中是否需要持续轮询?
在试图找出 这个问题(任何帮助表示赞赏)时,我跑了RXTX 在使用 PortMon 监控其活动时注意到 RXTX 不断检查是否数据可用,即使 Java 客户端仅通过 SerialPortEventListener 从 gnu.io.SerialPort 对象读取.
While trying to figure out this problem (any help there is appreciated), I ran RXTX while monitoring its activity using PortMon and noticed that RXTX constantly checks if data is available, even when the Java client reads from the gnu.io.SerialPort object only through a SerialPortEventListener.
这是为什么?是 RXTX 人的糟糕实现选择,Sun 糟糕的 API 选择(因为 RXTX 遵循 javax.comm API),还是本地代码支持的运行 Java 的限制?
Why is this? Is it a poor implementation choice by the RXTX folks, a poor API choice by Sun (since RXTX follows the javax.comm API), or a limitation of running Java supported by native code?
另一方面,超级终端不进行轮询(并且可以正常工作).它是否有权访问一些让它执行此操作的隐藏 Windows 系统调用?
Hyperterminal, on the other hand, does no polling (and works without a problem). Does it have access to some hidden Windows system calls that let it do this?
推荐答案
不,这不是由于 javax.xomm API.顺便说一句,Rxtx 可以通过该 API 使用,也可以不使用.
No it's not due to the javax.xomm API. Rxtx can be used through that API or not by the way.
Rxtx 的内部结构有点不同/奇怪,并且有一些错误.简短版本,它应该是这样工作的:你有两个参数可以使用:超时和阈值.根据源代码将超时设置为 0(无)和阈值设置为 1(在返回之前至少需要 1 个字节)应该给我们正常,由 InputStream 定义,阻塞读取.
Rxtx internals are a bit different/weird though and has some bugs. Short version, this is how it is supposed to work: You have two parameters to play with: timeout and threshold. According to the source code setting the timeout to 0 (none) and threshold to 1 (requiring at least 1 byte before returning) should give us normal, by InputStream defined, blocking reads.
问题是,即使这样设置,当前稳定版本 (2.1.7r2) 中也存在错误.阈值参数始终设置为 0!来自源代码:
The problem is that even when setting it up like this there is a bug in the current stable release (2.1.7r2). The threshold parameter is always set to 0! From the source code:
/* 测试 ttyset.c_cc[ VMIN ] = 阈值;*/ttyset.c_cc[ VMIN ] = 0;
/* TESTING ttyset.c_cc[ VMIN ] = threshold; */ ttyset.c_cc[ VMIN ] = 0;
令人困惑的是,2004 年也是如此,并在邮件列表中报告并修复了,但它要么没有真正修复,要么又回来了(回归).实际上有一个新的错误报告,由于某种原因我一开始找不到.我最终发现它会抛出预发布包的源代码,并找到了一个未发布的更改日志(在最后一个稳定版本之后,网页不显示更改日志,但它在 CVS 中可用).
The confusing part is that this was also the case in 2004 and reported on the mailing list and fixed, but it was either not really fixed or has come back again (a regression). There is actually a new bug report that for some reason I couldn’t find at first. I eventually found it going throw the pre-release package source code and found an otherwise not published change log (the web page doesn’t show change logs after the last stable version, its available in CVS though).
解决方案
- 已在 HEAD 上修复,因此您可以使用最新的预发布版本(2.2 系列)或从 CVS 编译.
按照以下方式制作一个丑陋的解决方法:
- It is fixed on HEAD, so you can use the latest pre-release version (2.2-series) or compile it from CVS.
Make an ugly workaround along the lines of:
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()
.
Then you do: read(in)
instead of in.read()
.
我实际上写了 一篇关于此的博客文章以前,所以我不会忘记.
I actually wrote a blog entry about this 2 years ago so I wouldn't forget.
相关文章