首先使用MINA框架要先下载框架所需的JAR包,这里给出我打包好的资源,需要的可以下载点击打开链接
言归正传,先来介绍服务器端(因为这个框架主要是用在服务器的,所以用在android设备上会比较耗资源,我用了这个测试工具,一般二十几台设备还是可以的)
1、创建一个非阻塞的Server端的Socket
IoAcceptor accept = new NioSocketAcceptor();
2、设置过滤器,这里可以使用MINA提供的文本换行符编解码器也可以用自定义的编解码器
(1)提供的
TextLineCodecFactory lineCode = new TextLineCodecFactory(Charset.forName("UTF-8"),LineDelimiter.WINDOWS.getValue(),LineDelimiter.WINDOWS.getValue());
这里还可以设置编解码的最大行的长度lineCode.setDecoderMaxLineLength(1024);lineCode.setEncoderMaxLineLength(1024);
然后acceptor.getFilterChain().addLast("codec",new ProtocolCodecFilter(lineCode));
(2)使用自定义的编解码器
这里先定义一个编解码的工厂类CharsetCodeFactory 实现ProtocolCodecFactory
public class CharsetCodecFactory implements ProtocolCodecFactory { @Override public ProtocolDecoder getDecoder(IoSession session) throws Exception {//返回一个解码器 return new CharsetDecoder(); } @Override public ProtocolEncoder getEncoder(IoSession session) throws Exception {//返回一个编码器 return new CharsetEncoder(); } } 编写编码器类
public class CharsetEncoder implements ProtocolEncoder { private static String TAG = "CharsetEncoder"; private final static Charset charset = Charset.forName("UTF-8"); @Override public void dispose(IoSession session) throws Exception { Log.d(TAG, "#############dispose############"); } @Override public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { Log.d(TAG, "#############字符编码############"); IoBuffer buff = IoBuffer.allocate(100).setAutoExpand(true);//设置缓冲区,根据传输内容大小自动变更 buff.putString(message.toString(), charset.newEncoder());//设置字符编码 // put 当前系统默认换行符 buff.putString(LineDelimiter.DEFAULT.getValue(), charset.newEncoder()); // 为下一次读取数据做准备 buff.flip(); out.write(buff); } } 编写解码器类 public class CharsetDecoder implements ProtocolDecoder { private static String TAG = "CharsetDecoder"; private final static Charset charset = Charset.forName("UTF-8"); // 可变的IoBuffer数据缓冲区 private IoBuffer buff = IoBuffer.allocate(100).setAutoExpand(true); @Override public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception { Log.d(TAG,"#########decode#########"); // 如果有消息 while (in.hasRemaining()) { // 判断消息是否是结束符,不同平台的结束符也不一样; // windows换行符(\r\n)就认为是一个完整消息的结束符了; UNIX 是\n;MAC 是\r byte b = in.get(); if (b == '\n') { buff.flip(); byte[] bytes = new byte[buff.limit()]; buff.get(bytes); String message = new String(bytes, charset); buff = IoBuffer.allocate(100).setAutoExpand(true); // 如果结束了,就写入转码后的数据 out.write(message); Log.d(TAG,"message: " + message); } else { buff.put(b); } } } @Override public void dispose(IoSession session) throws Exception { Log.d(TAG,"#########dispose#########"); Log.d(TAG,"============"+session.getCurrentWriteMessage()); } @Override public void finishDecode(IoSession session, ProtocolDecoderOutput out) throws Exception { Log.d(TAG,"#########完成解码#########"); } } 3、设置读取数据的缓冲区大小
acceptor.getSessionConfig().setReadBufferSize(2048);
4、设置读写的通道如果10秒内无操作就进入空闲状态
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE,10);
5、为接收器设置管理服务(核心处理)
acceptor.setHandler(new MyServerHandler());
其中MyServerHandler为封装好的逻辑处理类
/** * * @author huangdianhua * @date 2016年8月11日 下午1:03:51 */ public class MyServerHandler extends IoHandlerAdapter { private static String TAG = "MyServerHandler"; // 从端口接受消息,会响应此方法来对消息进行处理 @Override public void messageReceived(IoSession session, Object message) throws Exception { String msg = message.toString(); Log.d(TAG, "服务器接受消息成功..." + msg); // 拿到所有的客户端Session Collection<IoSession> sessions = session.getService().getManagedSessions().values(); // 向所有客户端发送数据 for (IoSession sess : sessions) { sess.write(msg); } } // 向客服端发送消息后会调用此方法 @Override public void messageSent(IoSession session, Object message) throws Exception { Log.d(TAG, "服务器发送消息成功..."); super.messageSent(session, message); } // 关闭与客户端的连接时会调用此方法 @Override public void sessionClosed(IoSession session) throws Exception { Log.d(TAG, "服务器与客户端断开连接..."); CloseFuture closeFuture = session.close(true); closeFuture.addListener(new IoFutureListener<IoFuture>() { public void operationComplete(IoFuture future) { if (future instanceof CloseFuture) { ((CloseFuture) future).setClosed(); } }; }); } // 服务器与客户端创建连接 @Override public void sessionCreated(IoSession session) throws Exception { Log.d(TAG, "服务器与客户端创建连接..."); } // 服务器与客户端连接打开 @Override public void sessionOpened(IoSession session) throws Exception { Log.d(TAG, "服务器与客户端连接打开..."); super.sessionOpened(session); } @Override public void sessionIdle(IoSession session, IdleStatus status) throws Exception { Log.d(TAG, "服务器进入空闲状态..."); super.sessionIdle(session, status); } @Override public void exceptionCaught(IoSession session, Throwable cause) throws Exception { Log.d(TAG, "服务器发送异常..."); super.exceptionCaught(session, cause); } } 6、绑定端口acceptor.bind(new InetSocketAddress(PORT));
以上就是服务器端的具体实现方式
下面介绍客户端的具体实现过程
1、创建一个连接器
IoConnector connector = new NioSocketConnector();
2、设置超时时间
connector.setConnectTimeoutMillis(3000);
3、添加过滤器(这个和服务器端的设置一样)
4、为接收器设置管理服务(这个也是和服务器是一样设置的)
connector.setHandler(new MinaClientHandler());
/** * * @author huangdianhua * @date 2016年8月11日 下午4:28:11 */ public class MinaClientHandler extends IoHandlerAdapter { private static String TAG = "MinaClientHandler"; @Override public void exceptionCaught(IoSession session, Throwable cause) throws Exception { Log.d(TAG, "客户端发生异常" + cause.getMessage()); super.exceptionCaught(session, cause); } @Override public void messageReceived(IoSession session, Object message) throws Exception { String msg = message.toString(); Log.d(TAG, "客户端接收到的信息为:" + msg); Intent intent = new Intent(); intent.setAction(CommonUtil.SEND_BROADCAST); intent.putExtra("name", msg); MyApplication.mContext.sendBroadcast(intent); super.messageReceived(session, message); } @Override public void messageSent(IoSession session, Object message) throws Exception { // TODO Auto-generated method stub super.messageSent(session, message); } }5、为连接器创建连接
ConnectFuture future = connector.connect(new InetSocketAddress(IP,PORT));//创建链接
future.awaitUninterruptibly();//等待连接创建完成
6、获得创建连接得到的session
session = future.getSession();
session.write("start");//写入信息
以上就是客户端的具体实现过程
参考点击打开链接