ja 串口

Ja串口通信至于通信程序,之前已经用事件驱动的方式开发了tcp和udp通信程序,程序在线运行稳定。后来在串口通信程序的开发中,采用了同样的方法,刚开始也没有问题。直到后来发现了大量的卡包问题。由于事件驱动,接收一次消息,处理一次消息,会导致消息堆积越来越多,处理延迟严重。由于包粘连的问题,实际收到的第一条消息是多帧消息粘连在一起,只处理第一条完整的消息。当下一条消息到达时,实际上处理的是前一条消息的第二条完整消息。事件驱动本身没有问题,问题是没有处理好。解决方法是在接收到一条消息后向缓冲区写一次,然后再启动一个线程,从缓冲区取数据并解包,这样可以实现消息接收、处理和发送的解耦。本来是基于netty开发的,但是感觉netty更适合开发网络通讯。但是,使用了netty的组件ByteBuf。以下代码仅提供了部分代码:串行侦听器serial =新串行侦听器(& # 34;COM1 & # 34, 9600);SerialTool.getSerialTool()。addListener(serial . get serial port(),serial);新线程(新运行(串行))。start();私有类Run实现Runnable { private serial listener serial;公共运行(serial listener serial){ this . serial = serial;} @ override public void run(){ while(true){ if(serial . get buf()。readable bytes()& gt;0){ try { decoder(serial . get buf());//处理缓冲区数据,解包,业务处理}最后{serial。getbuf()。discard read bytes();} utils . sleep(1);} }公共类SerialListener实现SerialPortEventListener { public byte buf get buf(){ return buf;} public void set buf(byte buf buf){ this . buf = buf;}私有SerialPort serialPort私有字符串端口;private byte buf buf = un pooled . buffer(1024,65535);public serial listener(String port,int bauddate){ serial port = serial tool . get serial tool()。openPort(port,baudtate);}/* * *处理被监控的串口事件*/public void串口事件(串口事件串口事件){switch(串口事件。geteventtype())。{案例序列号事件。data _ ailable://1有可用数据byte [] data = serialtool。getserialtool()。readfromport(串行端口);buf.writeBytes(数据);打破;案件序列号事件。BI: // 10通讯中断break案件序列号事件。OE: // 7溢出错误中断;案件序列号事件。FE: // 9帧错误中断;案件序列号事件。PE: // 8奇偶校验错误中断;案件序列号事件。CD: // 6载体检测中断;案件序列号事件。CTS: // 3清除要发送的中断数据;案件序列号事件。DSR: // 4要发送的数据准备断了;案件序列号事件。RI: // 5振铃表示断线;案例串行端口事件。output _ buffer _ empty://2输出缓冲区已被清除空break;默认:break} } }公共类SerialTool {私有静态SerialTool serialTool = null//私有化SerialTool类的构造方法,其他类不允许生成SerialTool对象private SerialTool() {} /** * *获取提供服务的SerialTool对象* @ Return serial tool */Public Static serial tool get serial tool(){ If(serial tool = = null){ serial tool = New serial tool();}返回serialTool}/* * *开放串口* @param portName端口名* @ parambaud baud rate * @ return串口对象* @ throwsserialportparameterfailure设置串口参数失败* @ throws NotASerialPort指向设备不是串口类型* @throws NoSuchPort没有对应的串口设备* @throws PortInUse端口已被占用*/public最终串口开放端口(stringportname,Int baudrate) {try {//标识端口CommPort标识符= CommPort标识符。通过端口名获取端口标识符(portname );//打开端口,给出端口名和超时(打开操作超时)com mport com mport = portidentifier . Open(port name,2000);//判断是否是串口if(串口的串口实例){串口串口=(串口)commport试试{//设置串口的波特率等参数。setserialportparams (baud,serialport.databits _ 8,serialport.stopbits _ 1,serial port . parity _ none);} catch(UnsupportedCommOperationException e){//抛出新的SerialPortParameterFailure();}//system . out . println(Open+port name+成功!);返回serialPort}else {//不是串口//throw new nota serial port();返回null} } catch(NoSuchPortException E1){//throw new NoSuchPort();} catch(PortInUseException E2){//throw new PortInUse();}返回null}/* * *关闭串口* @param serialport要关闭的串口对象*/public void Close port(Serial port Serial port){ if(Serial port!= null){ serial port . close();serialPort = null}}/* *向串口发送数据* @param serialPort串口对象* @param order要发送的数据* @ Throws SendDatatoserialPort失败向串口发送数据失败* @ throwsserialportoutputstreamclosefailure错误关闭串口对象的输出流*/public void Send to port(serial port,byte[]order){ output stream out = null;请尝试{ out = serial port . get output stream();out.write(顺序);out . flush();} catch(io exception e){//抛出新的SendDataToSerialPortFailure();}最后{试试{ if (out!= null){ out . close();out = null} } catch(io exception e){//throw new SerialPortOutputStreamCloseFailure();}}}/* *从串行端口读取数据* @param serialPort当前连接的串行端口对象* @ return read data from serial port失败错误从串行端口读取数据* @ throwsserialportinputstreamclosefailure */public byte[]readfromport(serial port){ inputstream in = null;byte[]bytes = null;请尝试{ in = serial port . getinputstream();int buff lenth = in . ailable();//获取数据长度while (bufflenth!= 0) { bytes =新字节[buff lenth];//将字节数组初始化为缓冲区中数据的长度in.read(字节);buff lenth = in . ailable();} } catch(io exception e){//throw new readdatafromsialportfailure();}最后{试试{如果(在!= null){ in . close();in = null} } catch(io exception e){//throw new SerialPortInputStreamCloseFailure();} }返回字节;}/* * * Add Listener * @ param port Serial Object * @ param Listener Serial Listeners * @ throws Too Many Listener监听太多类对象*/Public Void Add Listener(Serial port,Serialporteventlistener Listener){ try {//Add Listener port . addevent Listener(Listener)到串口;//设置端口。notifyondataailable (true)在数据到达时唤醒监控接收线程;//设置唤醒中断线程端口。当通信中断时,notifyonbreakinginterrupt (true );} catch(TooManyListenersException e){//throw new toomany listeners();}}

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。

发表回复

登录后才能评论