代码如下:package com.main2;import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.TooManyListenersException;public class Main {
public static void main(String[] args) {
try{
Test test = new Test();
test.start();
}catch(Exception e){
e.printStackTrace();
}
}
}
class Test extends Thread implements SerialPortEventListener {
static Enumeration portList;
static CommPortIdentifier portId;
static SerialPort serialPort;
static OutputStream outputStream;
static InputStream inputStream;
static BufferedReader br;
public Test(){
try{
portId = CommPortIdentifier.getPortIdentifier("COM3");
//打开通讯
serialPort = (SerialPort)portId.open("SimpleWriteApp", 2000);
serialPort.setRTS(false);
// serialPort.enableReceiveTimeout(0); //打开串口之后,读取之前
// serialPort.enableReceiveThreshold(0);
serialPort.setSerialPortParams(2400, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
}catch(Exception e){
e.printStackTrace();
}
} public void run() {
byte[] bt = new byte[]{(byte)0xaa,(byte)0x00,(byte)0xdb,(byte)0x01,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x55};
send(serialPort, bt);
}
private void send(SerialPort sPort, byte[] bt) {
try {
//发送命令
outputStream = sPort.getOutputStream();
outputStream.write(bt);
outputStream.flush();
outputStream.close();
System.out.println("command has been send");
Thread.sleep(100);
//接收返回值
sPort.setRTS(true);
inputStream = sPort.getInputStream();
br = new BufferedReader(new InputStreamReader(inputStream));
//注册事件监听
sPort.addEventListener(this);
sPort.notifyOnDataAvailable(true);
} catch (IOException e) {
e.printStackTrace();
}catch (TooManyListenersException e) {
e.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}
}
public synchronized void serialEvent(SerialPortEvent ev) {
try{
if (ev.getEventType() == ev.DATA_AVAILABLE){
//方法一 【抛出异常java.io.IOException : underlying input stream returned zero bytes】
String line = null;
while ((line=br.readLine()) != null) {
System.out.println("line = "+line);
}
//方法二 【打印结果为b=0 b=0】
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int ch;
while((ch=inputStream.read()) != -1){
bos.write(ch);
}
byte[] bt = bos.toByteArray();
bos.close();
for(byte b : bt){
System.out.print("b="+ b +"\t");
}
}
} catch (IOException e) {
e.printStackTrace();
}finally{
//关闭流和端口
try {
System.out.println("关闭端口");
if (br != null) {
br.close();
}
if(serialPort != null){
serialPort.close();
}
}catch(Exception e){
System.out.println("关闭端口时异常出现:"+e.getMessage());
}
}
}
}
使用方法一时异常信息如下:
java.io.IOException: Underlying input stream returned zero bytes
at sun.nio.cs.StreamDecoder$CharsetSD.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder$CharsetSD.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at com.main2.Test.serialEvent(Main.java:91)
at gnu.io.RXTXPort.sendEvent(RXTXPort.java:732)
at gnu.io.RXTXPort.eventLoop(Native Method)
at gnu.io.RXTXPort$MonitorThread.run(RXTXPort.java:1575)这段代码的功能是:通过串口向一块电路板发送一段命令,在发送命令前,设置RTS为关闭状态【如代码中】,发送以后,打开RTS【如代码中】,会收到返回值。发送命令是成功的,因为如果发送成功的话,会打开一个led灯。但是在读取返回值方面抛出了这个异常。
这个问题花了我整整一个月,也没有搞定,查了很多很多资料,试了很多种方法,都没有找到解决方案,google了这个异常,看到一些英文相关的论坛帖子,貌似这个是java的bug。
求各位大侠帮忙!时间还是比较紧的,搞不定的话,我自己都待不下去了之前本人发过类似的帖子:http://topic.csdn.net/u/20100611/20/8ceab9f5-68b1-4f6c-aec7-05280ae5f190.html
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.TooManyListenersException;public class Main {
public static void main(String[] args) {
try{
Test test = new Test();
test.start();
}catch(Exception e){
e.printStackTrace();
}
}
}
class Test extends Thread implements SerialPortEventListener {
static Enumeration portList;
static CommPortIdentifier portId;
static SerialPort serialPort;
static OutputStream outputStream;
static InputStream inputStream;
static BufferedReader br;
public Test(){
try{
portId = CommPortIdentifier.getPortIdentifier("COM3");
//打开通讯
serialPort = (SerialPort)portId.open("SimpleWriteApp", 2000);
serialPort.setRTS(false);
// serialPort.enableReceiveTimeout(0); //打开串口之后,读取之前
// serialPort.enableReceiveThreshold(0);
serialPort.setSerialPortParams(2400, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
}catch(Exception e){
e.printStackTrace();
}
} public void run() {
byte[] bt = new byte[]{(byte)0xaa,(byte)0x00,(byte)0xdb,(byte)0x01,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x55};
send(serialPort, bt);
}
private void send(SerialPort sPort, byte[] bt) {
try {
//发送命令
outputStream = sPort.getOutputStream();
outputStream.write(bt);
outputStream.flush();
outputStream.close();
System.out.println("command has been send");
Thread.sleep(100);
//接收返回值
sPort.setRTS(true);
inputStream = sPort.getInputStream();
br = new BufferedReader(new InputStreamReader(inputStream));
//注册事件监听
sPort.addEventListener(this);
sPort.notifyOnDataAvailable(true);
} catch (IOException e) {
e.printStackTrace();
}catch (TooManyListenersException e) {
e.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}
}
public synchronized void serialEvent(SerialPortEvent ev) {
try{
if (ev.getEventType() == ev.DATA_AVAILABLE){
//方法一 【抛出异常java.io.IOException : underlying input stream returned zero bytes】
String line = null;
while ((line=br.readLine()) != null) {
System.out.println("line = "+line);
}
//方法二 【打印结果为b=0 b=0】
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int ch;
while((ch=inputStream.read()) != -1){
bos.write(ch);
}
byte[] bt = bos.toByteArray();
bos.close();
for(byte b : bt){
System.out.print("b="+ b +"\t");
}
}
} catch (IOException e) {
e.printStackTrace();
}finally{
//关闭流和端口
try {
System.out.println("关闭端口");
if (br != null) {
br.close();
}
if(serialPort != null){
serialPort.close();
}
}catch(Exception e){
System.out.println("关闭端口时异常出现:"+e.getMessage());
}
}
}
}
使用方法一时异常信息如下:
java.io.IOException: Underlying input stream returned zero bytes
at sun.nio.cs.StreamDecoder$CharsetSD.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder$CharsetSD.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at com.main2.Test.serialEvent(Main.java:91)
at gnu.io.RXTXPort.sendEvent(RXTXPort.java:732)
at gnu.io.RXTXPort.eventLoop(Native Method)
at gnu.io.RXTXPort$MonitorThread.run(RXTXPort.java:1575)这段代码的功能是:通过串口向一块电路板发送一段命令,在发送命令前,设置RTS为关闭状态【如代码中】,发送以后,打开RTS【如代码中】,会收到返回值。发送命令是成功的,因为如果发送成功的话,会打开一个led灯。但是在读取返回值方面抛出了这个异常。
这个问题花了我整整一个月,也没有搞定,查了很多很多资料,试了很多种方法,都没有找到解决方案,google了这个异常,看到一些英文相关的论坛帖子,貌似这个是java的bug。
求各位大侠帮忙!时间还是比较紧的,搞不定的话,我自己都待不下去了之前本人发过类似的帖子:http://topic.csdn.net/u/20100611/20/8ceab9f5-68b1-4f6c-aec7-05280ae5f190.html
看情况你是先肯定电路板那里没问题咯?怎么排除电路板是没问题的呢?是用其他语言编写过样例程序通讯的么?如果是C语言,可以尝试拷贝C语言到java环境下。另外也可以考虑jni
Read text from a character-input stream, buffering characters so as to provide for the efficient reading of characters, arrays, and lines.
等接到消息了再去创建br呢?
inputStream = sPort.getInputStream();
br = new BufferedReader(new InputStreamReader(inputStream));这些调试过吗
2、我在测试的时候并不会只用这一种读取方法,我试了很多很多种,其中的一种也在发帖的时候写上去了,就是“方法二”。
The problem is that, at the end of a line, the GPS receiver sends a line feed character (ascii code = 10) and/or a carriage return character (ascii code = 13). Then, you must test if the current character stocked in your "line" variable (while ((line = in.readLine()) != null) ) is 10 or 13. If YES, you must break your while function to avoid reading the rest of the line. It should solve your problem. 下面是相关代关键码
Java代码
BufferedReader inStream = new BufferedReader(new InputStreamReader(inputStream));
byte ch = 0;
char myChar;
int charVal;
try{
while((ch = (byte)inStream.read()) != -1){
if((ch == 13) || (ch == 10)){ //In ASCII code: 13 = Carriage return, 10 = line feed. When the GPS receiver sends those characters, the while loop must be broken to avoid an IOException
break;
}else{
myChar = (char)ch;
charVal = myChar;
//System.out.print("byte=" + ch +" myChar=" + myChar + " charVal=" + charVal + "\n");
System.out.print(myChar);
}
}
上我的回答看看对你有没有帮助
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
public class Test extends Thread implements SerialPortEventListener {
static Enumeration portList;
static CommPortIdentifier portId;
static InputStream inputStream;
static OutputStream outputStream;
static SerialPort serialPort;
static int count = 0;
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("COM3")) {
Test test = new Test();
}
}
}
}
public Test() {
try {
//打开通讯
serialPort = (SerialPort) portId.open("ReadCommApp", 2000);
serialPort.setRTS(false);//此步骤可以省略,猜测默认情况即是false
serialPort.setSerialPortParams(2400, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
byte[] bt = new byte[]{(byte)0xaa,(byte)0x00,(byte)0xdd,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x55};
outputStream = serialPort.getOutputStream();
outputStream.write(bt);
outputStream.flush();
outputStream.close();
Thread.sleep(200); //50~~1400
serialPort.setRTS(true);
inputStream = serialPort.getInputStream();
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
} catch (Exception e) {
e.printStackTrace();
}
}
public void serialEvent(SerialPortEvent event) {
try{
if (event.getEventType() == event.DATA_AVAILABLE){
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int ch;
while((ch=inputStream.read()) != -1){
count++;
if(count>2){
bos.write(ch);
}
}
byte[] bt = bos.toByteArray();
for(byte b : bt){
System.out.print("b="+b+"\t");//b=-86 b=0 b=-35 b=3 b=0 b=0 b=85 b=85
}
bos.close();
}
}catch(Exception e){
e.printStackTrace();
}
}
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/config_man/archive/2010/06/30/5705264.aspx
我在博客里写的较为详细,大家如果不太明白的话,可以到我的博客里再看看。感谢各位网友的热心帮助!!!再次感谢!!!结贴!!!