Java基础知识:Javax.comm简介

精贴 置顶
1561 0

  Javax.comm是Sun公司提供的,用于开发平台独立的通讯应用程序的扩展API。(ps:这里javax的x很准确地表明了它是一个扩展包,而不是核心包(core package),但由于历史原因,javax下的并不都是扩展包,比如swing包已经是Java核心架构的一部分了,不过为了与Java1.1编码兼容,仍使用javax.swing。)javax.comm可以访问RS232接口(串口)及有限制地访问IEEE-1284(并口)。

  下载

  需要到其官方主页http://java.sun.com/products/javacomm/下载这个API,目前的最新版本是3.0。不过可惜的是,Sun目前没有推出此API在Windows平台下的3.0版本,主页上列出的三个版本,分别是运行在x86和Sparc结构下的Solaris系统,以及x86下的Linux系统。要下载Windows版本只能去寻找较老的版本了。我所找到的2个网址是http: //llk.media.mit.edu/projects/cricket/software/javaSerial.zip(两个文件夹里面有所需的 3个文件),http://mdubuc.freeshell.org/Jolt/javacomm20-win32.zip和(完整的2.0版本,还有 examples)。

  安装

  这里的所谓安装就是把三个重要的文件放到指定的目录下。

  将下载的文件解压缩后,在\javacomm20-win32\commapi目录下有必需的三个文件comm.jar,javax.comm. properties和win32comm.dll。将文件comm.jar拷贝到%JAVA_HOME%\jre\lib\ext;文件 javax.comm. properties拷贝到%JAVA_HOME%\jre\lib; 文件win32comm.dll拷贝到%JAVA_HOME%\bin。注意%JAVA_HOME%是jdk的路径,而非jre。

  API

  在javax.comm下有13个类和接口,分别是

  4个接口

  CommDriver 可负载设备(the loadable device)驱动程序接口的一部分

  CommPortOwnershipListener 传递各种通讯端口的所有权事件

  ParallelPortEventListener 传递并行端口事件

  SerialPortEventListener 传递串行端口事件

  6个类

  CommPort 通讯端口

  CommPortIdentifier 通讯端口管理

  ParallelPort 并行通讯端口

  ParallelPortEvent 并行端口事件

  SerialPort RS-232串行通讯端口

  SerialPortEvent 串行端口事件

  3个异常类

  NoSuchPortException 当驱动程序不能找到指定端口时抛出

  PortInUseException 当碰到指定端口正在使用中时抛出

  UnsupportedCommOperationException 驱动程序不允许指定操作时抛出

实例

  同API一起下载的还有一个examples文件,里面有6个程序。首先看最简单的读、写程序。

  读串口的例程


  import java.io.*;
  import java.util.*;
  import javax.comm.*;
  public class SimpleRead implements Runnable, SerialPortEventListener {
  static CommPortIdentifier portId;
  static Enumeration portList;//枚举类
  InputStream inputStream;
  SerialPort serialPort;
  Thread readThread;
  public static void main(String[] args) {
  portList = CommPortIdentifier.getPortIdentifiers();/*不带参数的getPortIdentifiers方法获得一个枚举对象,该对象又包含了系统中管理每个端口的CommPortIdentifier对象。注意这里的端口不仅仅是指串口,也包括并口。这个方法还可以带参数。getPortIdentifiers(CommPort)获得与已经被应用程序打开的端口相对应的CommPortIdentifier对象。 getPortIdentifier(String portName)获取指定端口名(比如“COM1”)的CommPortIdentifier对象。*/
  while (portList.hasMoreElements()) {
  portId = (CommPortIdentifier) portList.nextElement();
  if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL)/*getPortType方法返回端口类型*/ {
  // if (portId.getName().equals("COM1"))/* 找Windows下的第一个串口*/ {
  if (portId.getName().equals("/dev/term/a"))/*找Unix-like系统下的第一个串口*/ {
  SimpleRead reader = new SimpleRead();
  }
  }
  }
  }
  public SimpleRead() {
  try {
  serialPort = (SerialPort) portId.open("SimpleReadApp", 2000);/* open方法打开通讯端口,获得一个CommPort对象。它使程序独占端口。如果端口正被其他应用程序占用,将使用 CommPortOwnershipListener事件机制,传递一个PORT_OWNERSHIP_REQUESTED事件。每个端口都关联一个 InputStream 何一个OutputStream。如果端口是用open方法打开的,那么任何的getInputStream都将返回相同的数据流对象,除非有close 被调用。有两个参数,第一个为应用程序名;第二个参数是在端口打开时阻塞等待的毫秒数。*/
  } catch (PortInUseException e) {}
  try {
  inputStream = serialPort.getInputStream();/*获取端口的输入流对象*/
  } catch (IOException e) {}
  try {
  serialPort.addEventListener(this);/*注册一个SerialPortEventListener事件来监听串口事件*/
  } catch (TooManyListenersException e) {}
  serialPort.notifyOnDataAvailable(true);/*数据可用*/
  try {
  serialPort.setSerialPortParams(9600,
  SerialPort.DATABITS_8,
  SerialPort.STOPBITS_1,
  SerialPort.PARITY_NONE);/*设置串口初始化参数,依次是波特率,数据位,停止位和校验*/
  } catch (UnsupportedCommOperationException e) {}
  readThread = new Thread(this);
  readThread.start();
  }
  public void run() {
  try {
  Thread.sleep(20000);
  } catch (InterruptedException e) {}
  }
  //串口事件
  public void serialEvent(SerialPortEvent event) {
  switch(event.getEventType()) {
  case SerialPortEvent.BI:/*Break interrupt,通讯中断*/
  case SerialPortEvent.OE:/*Overrun error,溢位错误*/
  case SerialPortEvent.FE:/*Framing error,传帧错误*/
  case SerialPortEvent.PE:/*Parity error,校验错误*/
  case SerialPortEvent.CD:/*Carrier detect,载波检测*/
  case SerialPortEvent.CTS:/*Clear to send,清除发送*/
  case SerialPortEvent.DSR:/*Data set ready,数据设备就绪*/
  case SerialPortEvent.RI:/*Ring indicator,响铃指示*/
  case SerialPortEvent.OUTPUT_BUFFER_EMPTY:/*Output buffer is empty,输出缓冲区清空*/
  break;
  case SerialPortEvent.DATA_AVAILABLE:/*Data available at the serial port,端口有可用数据。读到缓冲数组,输出到终端*/
  byte[] readBuffer = new byte[20];
  try {
  while (inputStream.available() > 0) {
  int numBytes = inputStream.read(readBuffer);
  }
  System.out.print(new String(readBuffer));
  } catch (IOException e) {}
  break;
  }
  }
  }

  (PS:不推荐Thread的这种用法,详见《Core Java VolumeII》)

写串口的例程

  把字符串"Hello, world!\n"写到系统的第一个串口


    import java.io.*;
  import java.util.*;
  import javax.comm.*;
  public class SimpleWrite {
  static Enumeration portList;
  static CommPortIdentifier portId;
  static String messageString = "Hello, world!\n";
  static SerialPort serialPort;
  static OutputStream outputStream;
  public static void main(String[] args) {
  portList = CommPortIdentifier.getPortIdentifiers();
  while (portList.hasMoreElements()) {
  portId = (CommPortIdentifier) portList.nextElement();
  if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
  // if (portId.getName().equals("COM1")) {
  if (portId.getName().equals("/dev/term/a")) {
  try {
  serialPort = (SerialPort)
  portId.open("SimpleWriteApp", 2000);
  } catch (PortInUseException e) {}
  try {
  outputStream = serialPort.getOutputStream();
  } catch (IOException e) {}
  try {
  serialPort.setSerialPortParams(9600,
  SerialPort.DATABITS_8,
  SerialPort.STOPBITS_1,
  SerialPort.PARITY_NONE);
  } catch (UnsupportedCommOperationException e) {}
  try {
  outputStream.write(messageString.getBytes());
  } catch (IOException e) {}
  }
  }
  }
  }
  }

  上面两个例程都经过了简化,在打开端口,并且传输结束后没有关闭数据流和串口。在例程中我们看到CommPortIdentifier提供了打开通讯端口的方法open,但却没有相应关闭端口的方法,关闭端口需要调用javax.comm.CommPort类的close()。CommPort是这个包中的一个高级抽象,它定义了端口可作的各种事情:获取I/O数据流对象,控制缓冲区大小,调整输入的处理。

  • 没有任何评论
今日天气 ···

···

···

···

热门排行
用ASP实现网页BBS 2010-11-01
CSS cursor鼠标样式一览表 2012-06-25
.NET后台写JS代码 2011-11-03
网站地址多出jdfwkey的问题解析及... 2010-08-25
数据库xxx的日志已满,请备份该数... 2013-07-19
百度、google、Yahoo网站地图制作... 2011-01-30
<a>标签的伪类书写顺序问题... 2010-09-04
什么是长尾关键词? 2010-09-24
CEO名言 2010-08-31
Mysql 主从数据库同步 2010-09-12
博主推荐
本个人博客微信公众平台上线啦~~... 2013-10-13
饼哥网络互联上线啦~~要买域名空... 2013-09-20
网站title标题如何正确修改不会被... 2013-08-26
饼哥通讯录系统上线啦,欢迎大家... 2013-08-24
ASP .NET MYSQL 的简单分页 并不... 2013-08-19
网站有弹窗广告这样的站点,百度... 2013-08-17
做淘宝SEO优化需要注意的8大问题 2013-08-17
淘宝网怎么做SEO优化 2013-08-17
站长们要学习的“苍井空精神” 2013-08-17
苹果公司今日发布了iOS 7第五个开... 2013-08-07
随便看看
ASP中几种分页显示的比较 2010-11-01
Java base64 编码和解码案例 2013-06-26
JS取style里的值,只要数字不要P... 2010-09-12
站长警惕 十大元凶导致您的网站被... 2010-09-07
Bad Request 错误处理 2013-11-09
个人博客增加反向链接的35个技巧 2010-08-30
看来我也要捐点汽油! 2013-06-21
Android和iOS平台之战并没有赢家 2013-06-27
整型数据 2010-10-16
守住你的网站 防御DDoS攻击实用指... 2010-10-15
RSS新闻
传媒新闻
CSDN
八卦新闻
女性新闻
台湾新闻
互联网
军事-新浪博客
IT-新浪博客
汽车新闻
游戏新闻
国际新闻
国内新闻
体育新闻
我的微博
北京 上海 杭州 深圳 广州 成都