张世豪
21 小时以前 03b0fb0ba2de86bcfff277778826547c0e37a93f
src/chuankou/SerialPortService.java
@@ -10,234 +10,249 @@
public class SerialPortService {
    private SerialPort port;
    private volatile boolean capturing = false;
    private volatile boolean paused = true;
    private Thread readerThread;
    private Consumer<byte[]> responseConsumer;
    // 优化:重用缓冲区,减少内存分配
    private byte[] readBuffer = new byte[200];
    private ByteArrayOutputStream buffer = new ByteArrayOutputStream(1024);
    private Consumer<byte[]> dataReceivedCallback;
    // 新增:协议解析器引用
    private SerialProtocolParser protocolParser = new SerialProtocolParser();
    // 新增:数据条数计数器
    public static  int receivedDataCount = 0;
   private SerialPort port;
   private volatile boolean capturing = false;
   private volatile boolean paused = true;
   private Thread readerThread;
   private Consumer<byte[]> responseConsumer;
    // 其他现有方法保持不变...
    /**
     * 获取串口接收的数据条数
     * 当条数超过1万时自动从1开始重新计数
     * @return 数据条数字符串
     */
    public static String getReceivedDataCount() {
        receivedDataCount++;
        if (receivedDataCount > 10000) {
            receivedDataCount = 1;
        }
        return String.valueOf(receivedDataCount);
    }
    public static void setReceivedDataCount(int receivedDataCount) {
      SerialPortService.receivedDataCount = receivedDataCount;
   }
    /**
     * 获取协议解析器实例
     */
    public SerialProtocolParser getProtocolParser() {
        return protocolParser;
    }
   // 优化:重用缓冲区,减少内存分配
   private byte[] readBuffer = new byte[200];
   private ByteArrayOutputStream buffer = new ByteArrayOutputStream(1024);
   private Consumer<byte[]> dataReceivedCallback;
   // 新增:协议解析器引用
   private SerialProtocolParser protocolParser = new SerialProtocolParser();
   // 新增:数据条数计数器
   public static  int receivedDataCount = 0;
   // 其他现有方法保持不变...
   /**
     * 重置数据条数计数器
     */
    public void resetReceivedDataCount() {
        receivedDataCount = 0;
    }
    * 获取串口接收的数据条数
    * 当条数超过1万时自动从1开始重新计数
    * @return 数据条数字符串
    */
   public static String getReceivedDataCount() {
      receivedDataCount++;
      if (receivedDataCount > 10000) {
         receivedDataCount = 1;
      }
      return String.valueOf(receivedDataCount);
   }
    // 以下为原有代码,保持不变...
    public InputStream getInputStream() {
        if (port != null && port.isOpen()) {
            return port.getInputStream();
        }
        return null;
    }
   public static void setReceivedDataCount(int receivedDataCount) {
      SerialPortService.receivedDataCount = receivedDataCount;
   }
    public OutputStream getOutputStream() {
        if (port != null && port.isOpen()) {
            return port.getOutputStream();
        }
        return null;
    }
    public void setComPortTimeouts(int timeoutMode, int readTimeout, int writeTimeout) {
        if (port != null && port.isOpen()) {
            port.setComPortTimeouts(timeoutMode, readTimeout, writeTimeout);
        }
    }
    /**
     * 设置协议解析器
     */
    public void setProtocolParser(SerialProtocolParser parser) {
        this.protocolParser = parser;
    }
    /**
     * 启用调试输出,将接收到的数据打印到控制台
     */
    public void enableDebugOutput() {
        System.out.println("串口调试输出已启用 - 开始监听串口数据...");
    }
   /**
    * 获取协议解析器实例
    */
   public SerialProtocolParser getProtocolParser() {
      return protocolParser;
   }
    /**
     * 获取当前调试状态
     */
    public boolean isDebugEnabled() {
        return capturing;
    }
    public void startCapture() {
        if (dataReceivedCallback != null) {
            startCapture(dataReceivedCallback);
        } else {
            System.err.println("No data received callback set. Please call startCapture(Consumer<byte[]> onReceived) first.");
        }
   }
   /**
    * 重置数据条数计数器
    */
   public void resetReceivedDataCount() {
      receivedDataCount = 0;
   }
    /**
     * 打开串口
     */
    public boolean open(String portName, int baud) {
        if (port != null && port.isOpen()) {
            return true;
        }
   // 以下为原有代码,保持不变...
   public InputStream getInputStream() {
      if (port != null && port.isOpen()) {
         return port.getInputStream();
      }
      return null;
   }
        port = SerialPort.getCommPort(portName);
        port.setComPortParameters(baud, 8, 1, SerialPort.NO_PARITY);
        port.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 1, 0);
        protocolParser.start();
        return port.openPort();
    }
    public void setResponseConsumer(Consumer<byte[]> consumer) {
        this.responseConsumer = consumer;
    }
   public OutputStream getOutputStream() {
      if (port != null && port.isOpen()) {
         return port.getOutputStream();
      }
      return null;
   }
    /**
     * 关闭串口
     */
    public void close() {
        stopCapture();
        if (port != null && port.isOpen()) {
            port.closePort();
        }
        port = null;
    }
   public void setComPortTimeouts(int timeoutMode, int readTimeout, int writeTimeout) {
      if (port != null && port.isOpen()) {
         port.setComPortTimeouts(timeoutMode, readTimeout, writeTimeout);
      }
   }
    /**
     * 启动数据接收线程
     */
    public void startCapture(Consumer<byte[]> onReceived) {
        this.dataReceivedCallback = onReceived;
        if (capturing || port == null || !port.isOpen()) return;
        capturing = true;
        paused = false;
   /**
    * 设置协议解析器
    */
   public void setProtocolParser(SerialProtocolParser parser) {
      this.protocolParser = parser;
   }
        readerThread = new Thread(() -> {
            buffer.reset();
            long lastReceivedTime = 0;
            while (capturing && port.isOpen()) {
                long currentTime = System.currentTimeMillis();
                if (buffer.size() > 0 && (currentTime - lastReceivedTime) >= 20) {
                    byte[] data = buffer.toByteArray();
                    SystemDebugDialog.appendHexData(data);
                    // 新增:将数据传递给协议解析器
                    if (protocolParser != null) {
                        protocolParser.receiveData(data);
                    }
                    if (!paused) {
                        onReceived.accept(data);
                        if (responseConsumer != null) {
                            responseConsumer.accept(data);
                        }
                    }
                    buffer.reset();
                }
   /**
    * 启用调试输出,将接收到的数据打印到控制台
    */
   public void enableDebugOutput() {
      //System.out.println("串口调试输出已启用 - 开始监听串口数据...");
   }
                int len = port.readBytes(readBuffer, readBuffer.length);
                currentTime = System.currentTimeMillis();
   /**
    * 获取当前调试状态
    */
   public boolean isDebugEnabled() {
      return capturing;
   }
                if (len > 0) {
                    buffer.write(readBuffer, 0, len);
                    lastReceivedTime = currentTime;
                }
                if (len <= 0 && buffer.size() == 0) {
                    try { Thread.sleep(1); } catch (InterruptedException ignore) {}
                }
            }
            if (buffer.size() > 0) {
                byte[] data = buffer.toByteArray();
                SystemDebugDialog.appendHexData(data);
                // 新增:将数据传递给协议解析器
                if (protocolParser != null) {
                    protocolParser.receiveData(data);
                }
                if (!paused) {
                    onReceived.accept(data);
                    if (responseConsumer != null) {
                        responseConsumer.accept(data);
                    }
                }
            }
        });
        readerThread.setDaemon(true);
        readerThread.start();
    }
   public void startCapture() {
      if (dataReceivedCallback != null) {
         startCapture(dataReceivedCallback);
      } else {
         System.err.println("No data received callback set. Please call startCapture(Consumer<byte[]> onReceived) first.");
      }
   }
    /**
     * 停止数据接收线程
     */
    public void stopCapture() {
        capturing = false;
        if (readerThread != null) {
            try { readerThread.join(500); } catch (InterruptedException ignore) {}
            readerThread = null;
        }
    }
   /**
    * 打开串口
    */
   public boolean open(String portName, int baud) {
      if (port != null && port.isOpen()) {
         return true;
      }
    public void setPaused(boolean paused) {
        this.paused = paused;
    }
      port = SerialPort.getCommPort(portName);
      port.setComPortParameters(baud, 8, 1, SerialPort.NO_PARITY);
      port.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 1, 0);
      protocolParser.start();
      return port.openPort();
   }
    public boolean isPaused() {
        return paused;
    }
   public void setResponseConsumer(Consumer<byte[]> consumer) {
      this.responseConsumer = consumer;
   }
    public boolean isOpen() {
        return port != null && port.isOpen();
    }
   /**
    * 关闭串口
    */
   public void close() {
      stopCapture();
      if (port != null && port.isOpen()) {
         port.closePort();
      }
      port = null;
   }
    /**
     * 发送数据
     */
    public boolean send(byte[] data) {
        if (!isOpen()) {
            return false;
        }
        return port != null && port.isOpen() && port.writeBytes(data, data.length) > 0;
    }
   /**
    * 启动数据接收线程
    */
   public void startCapture(Consumer<byte[]> onReceived) {
      this.dataReceivedCallback = onReceived;
      if (capturing || port == null || !port.isOpen()) return;
      capturing = true;
      paused = false;
      readerThread = new Thread(() -> {
         buffer.reset();
         long lastReceivedTime = 0;
         while (capturing && port.isOpen()) {
            long currentTime = System.currentTimeMillis();
            if (buffer.size() > 0 && (currentTime - lastReceivedTime) >= 20) {
               byte[] data = buffer.toByteArray();
               SystemDebugDialog.appendHexData(data);
               // 新增:将数据传递给协议解析器
               if (protocolParser != null) {
                  protocolParser.receiveData(data);
               }
               if (!paused) {
                  onReceived.accept(data);
                  if (responseConsumer != null) {
                     responseConsumer.accept(data);
                  }
               }
               buffer.reset();
            }
            int len = port.readBytes(readBuffer, readBuffer.length);
            currentTime = System.currentTimeMillis();
            if (len > 0) {
               buffer.write(readBuffer, 0, len);
               lastReceivedTime = currentTime;
            }
            if (len <= 0 && buffer.size() == 0) {
               try { Thread.sleep(1); } catch (InterruptedException ignore) {}
            }
         }
         if (buffer.size() > 0) {
            byte[] data = buffer.toByteArray();
            SystemDebugDialog.appendHexData(data);
            // 新增:将数据传递给协议解析器
            if (protocolParser != null) {
               protocolParser.receiveData(data);
            }
            if (!paused) {
               onReceived.accept(data);
               if (responseConsumer != null) {
                  responseConsumer.accept(data);
               }
            }
         }
      });
      readerThread.setDaemon(true);
      readerThread.start();
   }
   /**
    * 停止数据接收线程
    */
   public void stopCapture() {
      capturing = false;
      if (readerThread != null) {
         try { readerThread.join(500); } catch (InterruptedException ignore) {}
         readerThread = null;
      }
   }
   public void setPaused(boolean paused) {
      this.paused = paused;
   }
   public boolean isPaused() {
      return paused;
   }
   public boolean isOpen() {
      return port != null && port.isOpen();
   }
   /**
    * 发送数据(优化版本)
    */
   public boolean send(byte[] data) {
      if (!isOpen()) {
         return false;
      }
      // 添加发送前的串口状态检查
      if (port == null || !port.isOpen()) {
         return false;
      }
      try {
         // 添加小延迟,避免连续发送
         Thread.sleep(2);
      } catch (InterruptedException e) {
         Thread.currentThread().interrupt();
         return false;
      }
      int result = port.writeBytes(data, data.length);
      return result > 0;
   }
}