Apache Mina Socket 与单片机通讯

来源:互联网 发布:蒙自管家婆软件 编辑:程序博客网 时间:2024/06/02 02:40
用以记录遇到的相关问题。(如需发送的是十六进制字符,需看另外一篇)
       一、Mina 介绍
              
ApacheMINA是一个网络应用程序框架,用来帮助用户简单地开发高性能和高可扩展性的网络应用程序。它提供了一个通过Java NIO在不同的传输例如TCP/IP和UDP/IP上抽象的事件驱动的异步API。
       
       问题描述:
                  使用JAVA 做Socket Server服务,C Socket作为客户端。通讯时Server端接收不到数据 ,Server发送的数据客户端收到是乱码。
       问题分析:
             1:
字节序
                由于JAVA使用的
字节序是big-endian格式而C语言的字节序在不同的地方使用的是不同的,C的字节序X86上是little-endian, solaris上是big-endian;
            2: 字符编码
               C使用的编码默认是
用mbcs, 而java上是用unicode(并且和标准的unicode还有些区别,可以参考java文档) 
     解决方式:
            对接收的数据和发出的数据重新进行编码,改成字节的方式来进行转化。


    核心代码说明:
         
private static SocketSever SocketSever = null;// 声明一个Soket服务端服务
private SocketAcceptor acceptor = new NioSocketAcceptor();// 创建一个非阻塞式Socket适配器
private DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();// 创建一个过滤器

       
private SocketSever() {
chain.addLast("logger", new LoggingFilter());
chain.addLast("codec", new ProtocolCodecFilter(
new MessageCodecFactory()));// 添加自定义编码过滤器
// 设置读取数据的缓冲区大小
acceptor.getSessionConfig().setReadBufferSize(2048);
// 读写通道10秒内无操作进入空闲状态
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
acceptor.setHandler(new TcpServerHandler());// 设置业务处理层类
try {
acceptor.bind(new InetSocketAddress(bindPort));// 绑定端口
} catch (IOException e) {
e.getStackTrace();
}
}
           
    自定义编码和解码方法
      
/**
 * 
 * 解码类
 * 
 * **/
public class MessageDecoder extends CumulativeProtocolDecoder {

public boolean doDecode(IoSession session, IoBuffer in,
ProtocolDecoderOutput out) throws Exception {
byte[] b = new byte[in.limit()];
in.get(b);
String msg = new String(b);
Message message = new Message();
message.setContent(msg);
out.write(message);
return true;

}
}

public class MessageEncoder implements ProtocolEncoder {
private final static Charset charset = Charset.forName("UTF-8");

public void dispose(IoSession session) throws Exception {

}

public void encode(IoSession session, Object message,
ProtocolEncoderOutput out) throws Exception {
  //由于我这边发送数据的时候是使用的message对象,所有在转化的时候是转成对象然后对对象里面的内容进行重新编码。 
Message myMessage = (Message) message;
IoBuffer buff = IoBuffer.allocate(100).setAutoExpand(true);//设置自动拓容
buff.putString(myMessage.getContent(), charset.newEncoder());//设置默认的编码机
buff.putString(LineDelimiter.DEFAULT.getValue(), charset.newEncoder());//根据系统设定编码
buff.flip();
out.write(buff);
}

public byte[] toBytes(String msg) {
ByteBuffer buff = ByteBuffer.allocate(msg.getBytes().length);
buff.put(msg.getBytes());
return buff.array();
}
}//end   MessageEncoder