Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用JSSC时如何从串行连接读取(所有可用)数据?_Java_Jssc - Fatal编程技术网

Java 使用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

我正在努力与JSSC合作。 我根据以下链接构建了我的应用程序:

我的事件处理程序如下所示:

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);
但是如果我这样做的话,我就不会在没有复制功能的情况下将消息分成一段(我将有两个单独的字节[],我需要它分成一段(字节[])

  • 可能吗
  • 当使用以太网(SocketChannel)时,我们可以使用ByteBuffer读取数据。但是使用JSSC我们不能

  • JSSC是否有一个好的替代方案

  • 谢谢

    您不能依靠任何图书馆一次提供您所需的所有内容,因为:

    • 图书馆不知道你需要多少数据
    • 该库将根据缓冲区、硬件等提供数据
    您必须开发自己的业务逻辑来处理数据包接收。这当然取决于数据包的定义:它们是否总是相同的长度,是否用相同的结束字符分隔,等等

    下面是一个与您的系统配合使用的示例(请注意,您应该将此作为一个开始,而不是一个完整的解决方案,例如,它不包括超时):

    静态类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();
            }