`
limititi
  • 浏览: 48856 次
  • 来自: ...
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

rxtx取代javax.comm实现Java跨平台设备端口通信(转)

阅读更多




rxtx取代javax.comm实现Java跨平台设备端口通信(转)

 

 

 

来源于http://blog.ednchina.com/hotpower/182484/message.aspx

 

通过修改sample例程,使用observer模式实现串口通信数据的订阅读取.

以下为俺的原创程序:

实现功能如下:

1. 在windows中监听指定的串口

2. observer模式订阅端口数据,可以有多个数据监听者同时接收数据

 

先到sun网站上下载串口通信库

http://java.sun.com/products/javacomm/index.jsp

再下载windows中的dll库

http://www.rxtx.org/

java实现源程序如下

 

------------------ 1 ---------------------

package serial;

import gnu.io.SerialPort;

import java.util.HashMap;

public class CommTest {

 /**
  * windows中串口通信程序需要rxtxSerial.dll的支持,放到D:\jdk1.5\bin目录下即可
  */
 public static void main(String[] args) {
  HashMap<String, Comparable> params = new HashMap<String, Comparable>();
  params.put(SerialReader.PARAMS_PORT, "COM8"); // 端口名称
  params.put(SerialReader.PARAMS_RATE, 9600); // 波特率
  params.put(SerialReader.PARAMS_TIMEOUT, 1000); // 设备超时时间 1秒
  params.put(SerialReader.PARAMS_DELAY, 200); // 端口数据准备时间 1秒
  params.put(SerialReader.PARAMS_DATABITS, SerialPort.DATABITS_8); // 数据位
  params.put(SerialReader.PARAMS_STOPBITS, SerialPort.STOPBITS_1); // 停止位
  params.put(SerialReader.PARAMS_PARITY, SerialPort.PARITY_NONE); // 无奇偶校验
  SerialReader sr = new SerialReader(params);

  CommDataObserver bob = new CommDataObserver("bob");
  CommDataObserver joe = new CommDataObserver("joe");
  sr.addObserver(joe);
  sr.addObserver(bob);
 }
}

 

---------------- 2 -----------------

package serial;

import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;

import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Observable;
import java.util.TooManyListenersException;

/**
 * 串口数据读取类,用于windows的串口数据读取
 *
 *
 * @author Macro Lu
 * @version 2007-4-4
 */
public class SerialReader extends Observable implements Runnable, SerialPortEventListener {
 static CommPortIdentifier portId;

 int delayRead = 200;

 int numBytes; // buffer中的实际数据字节数

 private static byte[] readBuffer = new byte[4096]; // 4k的buffer空间,缓存串口读入的数据

 static Enumeration portList;

 InputStream inputStream;

 SerialPort serialPort;

 HashMap serialParams;

 // 端口读入数据事件触发后,等待n毫秒后再读取,以便让数据一次性读完
 public static final String PARAMS_DELAY = "delay read"; // 延时等待端口数据准备的时间

 public static final String PARAMS_TIMEOUT = "timeout"; // 超时时间

 public static final String PARAMS_PORT = "port name"; // 端口名称

 public static final String PARAMS_DATABITS = "data bits"; // 数据位

 public static final String PARAMS_STOPBITS = "stop bits"; // 停止位

 public static final String PARAMS_PARITY = "parity"; // 奇偶校验

 public static final String PARAMS_RATE = "rate"; // 波特率

 /**
  * 初始化端口操作的参数.
  *
  *
  * @see
  */
 public SerialReader(HashMap params) {
  serialParams = params;
  init();

 }

 private void init() {
  try {
   // 参数初始化
   int timeout = Integer.parseInt(serialParams.get(PARAMS_TIMEOUT).toString());
   int rate = Integer.parseInt(serialParams.get(PARAMS_RATE).toString());
   int dataBits = Integer.parseInt(serialParams.get(PARAMS_DATABITS).toString());
   int stopBits = Integer.parseInt(serialParams.get(PARAMS_STOPBITS).toString());
   int parity = Integer.parseInt(serialParams.get(PARAMS_PARITY).toString());
   delayRead = Integer.parseInt(serialParams.get(PARAMS_DELAY).toString());

   String port = serialParams.get(PARAMS_PORT).toString();

   // 打开端口
   portId = CommPortIdentifier.getPortIdentifier(port);
   serialPort = (SerialPort) portId.open("SerialReader", timeout);
   inputStream = serialPort.getInputStream();
   serialPort.addEventListener(this);
   serialPort.notifyOnDataAvailable(true);
   serialPort.setSerialPortParams(rate, dataBits, stopBits, parity);

  } catch (PortInUseException e) {
   System.out.println("端口已经被占用!");
   e.printStackTrace();
  } catch (TooManyListenersException e) {
   System.out.println("端口监听者过多!");
   e.printStackTrace();
  } catch (UnsupportedCommOperationException e) {
   System.out.println("端口操作命令不支持!");
   e.printStackTrace();
  } catch (NoSuchPortException e) {
   System.out.println("端口不存在!");
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
  Thread readThread = new Thread(this);
  readThread.start();
 }

 /**
  * Method declaration
  *
  *
  * @see
  */
 public void run() {
  try {
   Thread.sleep(100);
  } catch (InterruptedException e) {
  }
 }

 /**
  * Method declaration
  *
  *
  * @param event
  *
  * @see
  */
 public void serialEvent(SerialPortEvent event) {
  try {
   // 等待1秒钟让串口把数据全部接收后在处理
   Thread.sleep(delayRead);
   System.out.print("serialEvent[" + event.getEventType() + "]    ");
  } catch (InterruptedException e) {
   e.printStackTrace();
  }

  switch (event.getEventType()) {

  case SerialPortEvent.BI: // 10
  case SerialPortEvent.OE: // 7
  case SerialPortEvent.FE: // 9
  case SerialPortEvent.PE: // 8
  case SerialPortEvent.CD: // 6
  case SerialPortEvent.CTS: // 3
  case SerialPortEvent.DSR: // 4
  case SerialPortEvent.RI: // 5
  case SerialPortEvent.OUTPUT_BUFFER_EMPTY: // 2
   break;
  case SerialPortEvent.DATA_AVAILABLE: // 1
   try {
    // 多次读取,将所有数据读入
    // while (inputStream.available() > 0) {
    // numBytes = inputStream.read(readBuffer);
    // }
    numBytes = inputStream.read(readBuffer);
    changeMessage(readBuffer, numBytes);
   } catch (IOException e) {
    e.printStackTrace();
   }
   break;
  }
 }

 // 通过observer pattern将收到的数据发送给observer
 // 将buffer中的空字节删除后再发送更新消息,通知观察者
 public void changeMessage(byte[] message, int length) {
  setChanged();
  byte[] temp = new byte[length];
  System.arraycopy(message, 0, temp, 0, length);
  // System.out.println("msg[" + numBytes + "]: [" + new String(temp) + "]");
  notifyObservers(temp);
 }

 static void listPorts() {
  Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();
  while (portEnum.hasMoreElements()) {
   CommPortIdentifier portIdentifier = (CommPortIdentifier) portEnum.nextElement();
   System.out.println(portIdentifier.getName() + " - "
     + getPortTypeName(portIdentifier.getPortType()));
  }
 }

 static String getPortTypeName(int portType) {
  switch (portType) {
  case CommPortIdentifier.PORT_I2C:
   return "I2C";
  case CommPortIdentifier.PORT_PARALLEL:
   return "Parallel";
  case CommPortIdentifier.PORT_RAW:
   return "Raw";
  case CommPortIdentifier.PORT_RS485:
   return "RS485";
  case CommPortIdentifier.PORT_SERIAL:
   return "Serial";
  default:
   return "unknown type";
  }
 }

 /**
  * @return A HashSet containing the CommPortIdentifier for all serial ports that are not
  *         currently being used.
  */
 public static HashSet<CommPortIdentifier> getAvailableSerialPorts() {
  HashSet<CommPortIdentifier> h = new HashSet<CommPortIdentifier>();
  Enumeration thePorts = CommPortIdentifier.getPortIdentifiers();
  while (thePorts.hasMoreElements()) {
   CommPortIdentifier com = (CommPortIdentifier) thePorts.nextElement();
   switch (com.getPortType()) {
   case CommPortIdentifier.PORT_SERIAL:
    try {
     CommPort thePort = com.open("CommUtil", 50);
     thePort.close();
     h.add(com);
    } catch (PortInUseException e) {

     System.out.println("Port, " + com.getName() + ", is in use.");

    } catch (Exception e) {
     System.out.println("Failed to open port " + com.getName() + e);
    }
   }
  }
  return h;
 }

}

 

---------- 3 -----------------

package serial;

import java.util.Observable;
import java.util.Observer;

class CommDataObserver implements Observer {
 String name;

 public CommDataObserver(String name) {
  this.name = name;
 }

 public void update(Observable o, Object arg) {
  System.out.println("[" + name + "] GetMessage:\n [" + new String((byte[]) arg) + "]");
 }
}

 

分享到:
评论

相关推荐

    javax.comm jar包

    javax.comm 是一个Java API,它提供了与串行通信硬件...在使用过程中,需要考虑兼容性和替代方案,因为现代的Java开发可能更多地依赖于如RXTX、JSerialComm这样的第三方库,它们提供了更现代的API和更好的跨平台支持。

    java 串口通信 包 comm.jar

    对于现代的Java应用,开发者可能会转向第三方库,如RXTX或JSerialComm,这些库提供了更广泛的支持和更好的跨平台兼容性。 总的来说,`comm.jar`是Java实现串口通信的基础,虽然存在一些限制,但在许多旧项目或特定...

    RXTX 2.0 for use WITH Sun's CommAPI (namespace javax.comm)

    5. **跨平台兼容性**:除了win32版本,RXTX还支持其他操作系统,如Linux、Mac OS X等,这使得开发跨平台的串行通信应用变得可能。 6. **线程安全**:RXTX库的设计考虑到了多线程环境,确保在并发环境下操作串行端口...

    javacomm20-win32.rar_JAVA comm不_Java 串口通信_javacomm20_javacomm20-

    `javacomm20-win32.rar`这个压缩包包含了一个适用于Windows系统的Java串口通信组件,它允许Java应用程序通过串行端口与外部设备进行数据交换。`javacomm20`是这个库的版本号,暗示这是一个较早的实现,可能针对JDK ...

    JAVA串口COMM包

    Java串口通信(JAVA串口COMM包)是Java平台中用于实现串行通信的一个关键工具,主要用于设备间的低级通信,如与打印机、Modem、GPS等硬件设备交互。这个包由Java Micro Edition (Java ME) 提供,使得开发者能够在...

    JAR(comm和rxtx)

    6. **兼容性和测试**:由于javax.comm的过时和rxtx的跨平台特性,开发者需要在目标系统上进行充分的测试,确保通信功能在所有支持的环境中都能正常工作。 综上所述,这个压缩包提供的是两个关键的Java通信库,适用...

    javacomm20-win32.zip_j2me_java comm w_javacomm20 win32_javacomm2

    总之,Java Comm API为Java开发者提供了一种跨平台的方式来实现串口通信,尤其在J2ME环境下,对于嵌入式设备和物联网应用来说非常重要。通过这个库,开发者可以编写应用程序,实现与硬件设备的交互,例如读写传感器...

    Java+Communication+API.rar_comm2.0.3.zip_comm3.0_u1_linux.zip_ja

    总的来说,Java Comm API为Java开发者提供了一种跨平台的途径,去与硬件设备进行通信,特别是在需要控制串行设备或实现自动化系统时,它是非常有用的工具。虽然它可能需要更多的配置和对底层硬件的理解,但其标准化...

    Java串口开发包 RXTX.7z

    它实现了Java Communications API(javax.comm),使得开发者可以使用标准的API进行串口操作。 2. **SerialPort**: 这个类代表串行端口,提供了打开、关闭、读取、写入数据以及配置串口参数的方法。开发者可以通过...

    JavaComm说明

    5. **跨平台兼容**:尽管JavaComm在不同操作系统上可能需要不同的驱动支持,但其API设计是统一的,这使得编写跨平台的通信程序变得容易。 **使用JavaComm的注意事项**: 1. **驱动安装**:在某些平台上,可能需要...

    java-Comm-API.rar_comm

    4. **兼容性问题**: 由于Java Comm API依赖于操作系统提供的底层驱动,因此它的跨平台性受到一定限制。在Windows、Linux和Mac OS上,可能需要安装额外的驱动程序或库才能使Java Comm API正常工作。 5. **应用领域**...

    java comm api.rar

    Java通信API(Comm API)是Java平台上的一个接口,用于实现与硬件设备,特别是串行和并行端口的通信。这个API使得开发者能够用Java编写应用程序,与各种硬件设备进行交互,比如打印机、调制解调器或者自定义的硬件...

    java-rxtx串口通信读取电子秤数据全源码包win7x64

    RXTX是一个跨平台的Java库,支持串行(Serial)和并行(Parallel)通信。它提供了一组与Java标准的`javax.comm`包相类似的API,但功能更强大,兼容性更好,尤其是在Linux和Mac OS X等非Windows平台上。在Windows系统...

    Java串口通信编程指南.doc

    此外,开源项目Rxtx提供了跨平台的串口通信解决方案,但本文将重点介绍如何在Windows平台下使用Java Communication API进行串口通信。 ### 一、前期准备 #### 1.1 下载Java Communication包 Java Communication包...

    rxtx-2.1-7-bins-r2.zip_RXTX-2.1-7_Rxtx.zip_rxtx_smpp_短信协议 smpp

    5. **兼容性**:RXTX库兼容Java串行接口规范,可以与Java Communications API (javax.comm)无缝协作。 SMPP(Short Message Peer-to-Peer)协议,是专为短信服务设计的一种应用层协议,常用于短信网关。它允许服务...

    javacomm20-win32.zip

    这些接口和类为Java应用程序提供了一个标准的、跨平台的方式来控制串行和并行通信。 2. **Platform-specific drivers**: Java Comm API依赖于特定操作系统的驱动程序来实现实际的串行通信。对于Windows平台,这个...

    精伦设备iDR210/iDR200 java实现

    Java提供了多种方式来实现设备通信,如使用Java Native Interface (JNI) 调用本地库,或者利用Java的串口通信库如RXTX或javax.comm来处理串口数据。对于精伦设备,可能需要通过特定的通信协议,如TCP/IP或串行接口...

    java串口通信.zip

    在Java中,我们可以使用`javax.comm`包来实现串口操作,但这个包并不是Java标准库的一部分,需要单独下载和添加到项目中。另一个选择是使用第三方库,如RXTX库,它提供了更现代且跨平台的串口API。 在描述中提到了...

    java通过com口采集读取modbus数据驱动程序

    然而,需要注意的是,`javax.comm`库在Java 6之后不再维护,因此可能需要寻找替代方案,如RXTX库,这是一个开源的、跨平台的串行通信API,支持Windows、Linux和Mac OS X等操作系统。 接下来,你需要理解Modbus协议...

    Java串口通信实例

    在Java中,我们可以利用`javax.comm`库(或第三方库如RXTX)来实现串口通信。 `javax.comm`是Java提供的一套用于访问串口的API,但需要注意的是,这个库在Java 6之后并未被官方继续维护,可能需要单独下载并配置到...

Global site tag (gtag.js) - Google Analytics