Java 使用JSSC时如何从串行连接读取(所有可用)数据?
我正在努力与JSSC合作。 我根据以下链接构建了我的应用程序: 我的事件处理程序如下所示:Java 使用JSSC时如何从串行连接读取(所有可用)数据?,java,jssc,Java,Jssc,我正在努力与JSSC合作。 我根据以下链接构建了我的应用程序: 我的事件处理程序如下所示: static class SerialPortReader implements SerialPortEventListener { public void serialEvent(SerialPortEvent event) { if(event.isRXCHAR()){//If data is available
static class SerialPortReader implements SerialPortEventListener {
public void serialEvent(SerialPortEvent event) {
if(event.isRXCHAR()){//If data is available
try {
byte buffer[] = serialPort.readBytes();
}
catch (SerialPortException ex) {
System.out.println(ex);
}
}
}
}
}
问题是我总是不能完整地获取传入的数据。(I消息长度为100字节,Im在两次单独调用中分别获得48和52字节)
-另一方以不同的长度向我发送消息。-在我使用的ICD中,有一个字段告诉我们消息的长度。(从字节10到字节13) -我看不懂14个字节:
(serialPort.readBytes(14);,
解析消息长度并读取消息的其余部分:
(serialPort.readBytes(messageLength-14);
但是如果我这样做的话,我就不会在没有复制功能的情况下将消息分成一段(我将有两个单独的字节[],我需要它分成一段(字节[])
谢谢您不能依靠任何图书馆一次提供您所需的所有内容,因为:
- 图书馆不知道你需要多少数据
- 该库将根据缓冲区、硬件等提供数据
静态类SerialPortReader实现SerialPortEventListener
{
private int m_nReceptionPosition=0;
私有布尔m_bReceptionActive=false;
专用字节[]m_aReceptionBuffer=新字节[2048];
@凌驾
public void serialEvent(SerialPortEvent p_oEvent)
{
字节[]aReceiveBuffer=新字节[2048];
int-nLength=0;
int-nByte=0;
开关(p_oEvent.getEventType())
{
案例SerialPortEvent.RXCHAR:
尝试
{
aReceiveBuffer=serialPort.readBytes();
对于(nByte=0;nByte=2047)
{
//为下一个数据包重置
m_bReceptionActive=假;
m_nReceptionPosition=0;
}
else if(m_bReceptionActive)
{
m_nReceptionPosition++;
//至少接收包括长度的数据包的开始
如果(m_nReceptionPosition>=14)
{
nLength=(短)((短)m_aReceptionBuffer[10]&0x000000FF);
nLength |=((短)m|u aReceptionBuffer[11]在将数据写入串行端口后,需要刷新数据。检查时间,并注意只有在另一端写入数据后才应进行读取。读取大小只是读取系统调用的指示,不能保证。数据可能已到达并缓冲在串行端口硬件缓冲区中,但可能尚未传输到操作系统缓冲区不适用于应用程序。考虑使用SCM库,它在每次写入后刷新数据 试试:
将数据写入串行端口(使用serialPort.writeBytes()),如果需要响应,请使用以下命令:
byte[] getData() throws SerialPortException, IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] b;
try {
while ((b = serialPort.readBytes(1, 100)) != null) {
baos.write(b);
// System.out.println ("Wrote: " + b.length + " bytes");
}
// System.out.println("Returning: " + Arrays.toString(baos.toByteArray()));
} catch (SerialPortTimeoutException ex) {
; //don't want to catch it, it just means there is no more data to read
}
return baos.toByteArray();
}
对返回的字节数组执行您想要的操作;在我的例子中,我只是显示它以供测试
我发现如果你每次读取一个字节,使用100毫秒的超时时间,并且当它超时时,你已经读取了缓冲区中的所有数据,那么它就可以正常工作
来源:尝试使用jssc和ESC/POS与爱普生串行打印机对话。你不能假设一次就获得完整数据,这很可能永远不会发生。如果消息总是100字节,你只需要在变量中输入数据,并在获得100字节后触发业务代码,然后重置变量。如果你有特定的SOH或结束字符,您可以相应地触发。如何注册到结束字符事件?
byte[] getData() throws SerialPortException, IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] b;
try {
while ((b = serialPort.readBytes(1, 100)) != null) {
baos.write(b);
// System.out.println ("Wrote: " + b.length + " bytes");
}
// System.out.println("Returning: " + Arrays.toString(baos.toByteArray()));
} catch (SerialPortTimeoutException ex) {
; //don't want to catch it, it just means there is no more data to read
}
return baos.toByteArray();
}