mina串口需要依靠的包
前几个包可以mina官网下载,最后一个minamycom.jar是我自己把org.apache.mina.transport.serial下的所有class打成的jar(http://m134.mail.qq.com/cgi-bin/frame_html?sid=H-tEBtnqbtrjOH4z&r=6e9e4c331cf2c905cc15bf23d15f5a27 下载)
主要是解决串口读数据一次最多读32个字节的问题,解决后通过传递一个参数来解决串口直到把所有数据一次性全部读出
1) rxtx-2.1-7-bins-r2下的
把rxtxParallel.dll,rxtxSerial.dll拷贝到Java\jdk1.6.0_10\jre\bin
把RXTXcomm.jar拷贝到Java\jdk1.6.0_10\jre\lib\ext
环境变量中添加CLASSPATH=;C:\Program Files\Java\jdk1.6.0_10\jre\lib\ext\RXTXcomm.jar
2)下载了apache-mina-2.0.2-src.zip找到src下的mina-transport-serial把其中的org及其以下的目录放在myeclipse项目的src下
修改org.apache.mina.transport.serial包下的SerialSessionImpl.java如下
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.mina.transport.serial;
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.io.OutputStream;
import java.util.TooManyListenersException;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.filterchain.DefaultIoFilterChain;
import org.apache.mina.core.filterchain.IoFilterChain;
import org.apache.mina.core.service.DefaultTransportMetadata;
import org.apache.mina.core.service.IoProcessor;
import org.apache.mina.core.service.IoServiceListenerSupport;
import org.apache.mina.core.service.TransportMetadata;
import org.apache.mina.core.session.AbstractIoSession;
import org.apache.mina.core.write.WriteRequest;
import org.apache.mina.util.ExceptionMonitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* An imlpementation of SerialSession}.
*
* @author <a href="apache/'>http://mina.apache.org">Apache MINA Project</a>
*/
class SerialSessionImpl extends AbstractIoSession implements SerialSession, SerialPortEventListener {
static final TransportMetadata METADATA = new DefaultTransportMetadata("rxtx", "serial", false, true,
SerialAddress.class, SerialSessionConfig.class, IoBuffer.class);
private final IoProcessor<SerialSessionImpl> processor = new SerialIoProcessor();
private final IoFilterChain filterChain;
private final IoServiceListenerSupport serviceListeners;
private final SerialAddress address;
private final SerialPort port;
private final Logger log;
private InputStream inputStream;
private OutputStream outputStream;
SerialSessionImpl(SerialConnector service, IoServiceListenerSupport serviceListeners, SerialAddress address,
SerialPort port) {
super(service);
config = new DefaultSerialSessionConfig();
this.serviceListeners = serviceListeners;
filterChain = new DefaultIoFilterChain(this);
this.port = port;
this.address = address;
log = LoggerFactory.getLogger(SerialSessionImpl.class);
}
public SerialSessionConfig getConfig() {
return (SerialSessionConfig) config;
}
public IoFilterChain getFilterChain() {
return filterChain;
}
public TransportMetadata getTransportMetadata() {
return METADATA;
}
public SerialAddress getLocalAddress() {
return null; // not applicable
}
public SerialAddress getRemoteAddress() {
return address;
}
@Override
public SerialAddress getServiceAddress() {
return (SerialAddress) super.getServiceAddress();
}
public void setDTR(boolean dtr) {
port.setDTR(dtr);
}
public boolean isDTR() {
return port.isDTR();
}
public void setRTS(boolean rts) {
port.setRTS(rts);
}
public boolean isRTS() {
return port.isRTS();
}
/**
* start handling streams
*
* @throws IOException
* @throws TooManyListenersException
*/
void start() throws IOException, TooManyListenersException {
inputStream = port.getInputStream();
outputStream = port.getOutputStream();
ReadWorker w = new ReadWorker();
w.start();
port.addEventListener(this);
((SerialConnector) getService()).getIdleStatusChecker0().addSession(this);
try {
getService().getFilterChainBuilder().buildFilterChain(getFilterChain());
serviceListeners.fireSessionCreated(this);
} catch (Throwable e) {
getFilterChain().fireExceptionCaught(e);
processor.remove(this);
}
}
private final Object writeMonitor = new Object();
private WriteWorker writeWorker;
private class WriteWorker extends Thread {
@Override
public void run() {
while (isConnected() && !isClosing()) {
flushWrites();
// wait for more data
synchronized (writeMonitor) {
try {
writeMonitor.wait();
} catch (InterruptedException e) {
log.error("InterruptedException", e);
}
}
}
}
}
private void flushWrites() {
for (;;) {
WriteRequest req = getCurrentWriteRequest();
if (req == null) {
req = getWriteRequestQueue().poll(this);
if (req == null) {
break;
}
}
IoBuffer buf = (IoBuffer) req.getMessage();
if (buf.remaining() == 0) {
setCurrentWriteRequest(null);
buf.reset();
this.getFilterChain().fireMessageSent(req);
continue;
}
int writtenBytes = buf.remaining();
try {
outputStream.write(buf.array(), buf.position(), writtenBytes);
buf.position(buf.position() + writtenBytes);
// increase written bytes
increaseWrittenBytes(writtenBytes, System.currentTimeMillis());
setCurrentWriteRequest(null);
buf.reset();
// fire the message sent event
getFilterChain().fireMessageSent(req);
} catch (IOException e) {
this.getFilterChain().fireExceptionCaught(e);
}
}
}
private final Object readReadyMonitor = new Object();
int dataSize;
// long l1=0;
private class ReadWorker extends Thread {
@Override
public void run() {
while (isConnected() && !isClosing()) {
synchronized (readReadyMonitor) {
try {
readReadyMonitor.wait();
} catch (InterruptedException e) {
log.error("InterruptedException", e);
}
if (isClosing() || !isConnected()) {
break;
}
try {
/*if(l1==0){
l1=System.currentTimeMillis();
}else{
long l2=System.currentTimeMillis();
System.out.println(l2-l1);
l1=l2;
}*/
while(inputStream.available()>dataSize){
dataSize = inputStream.available();
Thread.sleep(address.getWaitMs());//参数一般是200毫秒,这个参数也可以自己输入我的电脑每次读数据的间隔是200毫秒左右
}
byte[] data = new byte[dataSize];
int readBytes = inputStream.read(data);
if (readBytes > 0) {
IoBuffer buf = IoBuffer.wrap(data, 0, readBytes);
buf.put(data, 0, readBytes);
buf.flip();
getFilterChain().fireMessageReceived(buf);
}
dataSize=0;
} catch (IOException e) {
getFilterChain().fireExceptionCaught(e);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public void serialEvent(SerialPortEvent evt) {
if (evt.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
synchronized (readReadyMonitor) {
readReadyMonitor.notifyAll();
}
}
}
@Override
public IoProcessor<SerialSessionImpl> getProcessor() {
return processor;
}
private class SerialIoProcessor implements IoProcessor<SerialSessionImpl> {
public void add(SerialSessionImpl session) {
// It's already added when the session is constructed.
}
public void flush(SerialSessionImpl session) {
if (writeWorker == null) {
writeWorker = new WriteWorker();
writeWorker.start();
} else {
synchronized (writeMonitor) {
writeMonitor.notifyAll();
}
}
}
public void remove(SerialSessionImpl session) {
try {
inputStream.close();
} catch (IOException e) {
ExceptionMonitor.getInstance().exceptionCaught(e);
}
try {
outputStream.close();
} catch (IOException e) {
ExceptionMonitor.getInstance().exceptionCaught(e);
}
try { // Turn flow control off right before close to avoid deadlock
port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
} catch (UnsupportedCommOperationException e) {
ExceptionMonitor.getInstance().exceptionCaught(e);
}
port.close();
flush(session);
synchronized (readReadyMonitor) {
readReadyMonitor.notifyAll();
}
serviceListeners.fireSessionDestroyed(SerialSessionImpl.this);
}
public void updateTrafficControl(SerialSessionImpl session) {
throw new UnsupportedOperationException();
}
public void dispose() {
// Nothing to dispose
}
public boolean isDisposed() {
return false;
}
public boolean isDisposing() {
return false;
}
}
}
3)测试程序:
package com;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.core.session.IoSessionConfig;
import org.apache.mina.transport.serial.SerialAddress;
import org.apache.mina.transport.serial.SerialConnector;
import org.apache.mina.transport.serial.SerialAddress.DataBits;
import org.apache.mina.transport.serial.SerialAddress.FlowControl;
import org.apache.mina.transport.serial.SerialAddress.Parity;
import org.apache.mina.transport.serial.SerialAddress.StopBits;
public class Test {
public static void main(String[] args) {
SerialConnector connector = new SerialConnector();
connector.setHandler(new myComHandler());//DataBits dataBits, StopBits stopBits, Parity parity, FlowControl flowControl
SerialAddress portAddress=new SerialAddress( "COM5", 2400,DataBits.DATABITS_8, StopBits.BITS_1, Parity.EVEN, FlowControl.XONXOFF_IN,new Long(200));
ConnectFuture future = connector.connect(portAddress);
try {
future.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
IoSession sessin = future.getSession();
// sessin.getFilterChain().addFirst("first", new addfilter());
IoSessionConfig sc=sessin.getService().getSessionConfig();
sessin.setAttribute("comname", "COM5");
String s="1111111111111111111111111111111111111111111111111111111111111111111111";
s=s.replace(" ", "");
System.out.println(s);
byte[]b=Convert.hexStringToBytes(s);
sessin.write(Convert.byteToIoBuffer(b, b.length));
connector.dispose();
}
}