浅谈MINA的使用

来源:互联网 发布:理性 知乎 编辑:程序博客网 时间:2024/05/29 07:10

http://blog.csdn.net/yuan16423276

最近做了一个POS终端通信的小项目,主要是给POS终端提供TCP接口。之前的工作中没有从事相关的开发,也没涉及到网络通信的相关框架,在网上找了一些相关资料,最终选用了apache下的mina框架。

mina框架是一个网络通信框架,也就是它是基于TCP/IP、UDP/IP的协议栈的通信框架。mina对Java的socket进行了封装,我们在使用mina时不用把过多的精力放在网络通信的开发上,mina给我们提供了事件驱动、异步它的异步默认使用的是java noi作为异步支持。同时mina对通信的客户端和服务端都进行了封装,我们可以轻松的使用mina进行服务端可客户端的开发。

(1.) IoService:这个接口在一个线程上负责套接字的建立,拥有自己的Selector,监听是否有连接被建立。

(2.) IoProcessor:这个接口在另一个线程上,负责检查是否有数据在通道上读写,也就是说它也拥有自己的Selector,这是与我们使用JAVA NIO 编码时的一个不同之处,通常在JAVA NIO 编码中,我们都是使用一个Selector,也就是不区分IoService与IoProcessor 两个功能接口。另外,IoProcessor 负责调用注册在IoService 上的过滤器,并在过滤器链之后调用IoHandler。
(3.) IoFilter:这个接口定义一组拦截器,这些拦截器可以包括日志输出、黑名单过滤、数据的编码(write 方向)与解码(read 方向)等功能,其中数据的encode 与decode是最为重要的、也是你在使用Mina 时最主要关注的地方。
(4.) IoHandler:这个接口负责编写业务逻辑,也就是接收、发送数据的地方。

废话不多说,以下是我自己编写的服务端程序,贴出来供大家参考学习:

[java] view plain copy
  1. import java.net.InetSocketAddress;  
  2.   
  3. import org.apache.log4j.Logger;  
  4. import org.apache.mina.core.session.IdleStatus;  
  5. import org.apache.mina.filter.codec.ProtocolCodecFilter;  
  6. import org.apache.mina.transport.socket.nio.NioSocketAcceptor;  
  7.   
  8. import com.chinaums.umscard.socket.codec.MsgCodecFactory;  
  9. import com.chinaums.umscard.util.BaseConfig;  
  10.   
  11. public class MinaServer {  
  12.   
  13.     private static final Logger log = Logger.getLogger(MinaServer.class);  
  14.       
  15.     public static void main(String[] args) {  
  16.         // 创建一个非阻塞的server端的Socket  
  17.         NioSocketAcceptor acceptor = new NioSocketAcceptor();  
  18.         try {  
  19.             // 设置过滤器(使用自己封装的编解码器)  
  20.             acceptor.getFilterChain().addLast("codec",new ProtocolCodecFilter(new MsgCodecFactory("UTF-8")));  
  21.               
  22.             // 设置读取数据的缓冲区大小为1M  
  23.             acceptor.getSessionConfig().setReadBufferSize(1024*1024);  
  24.             // 读写通道10秒内无操作进入空闲状态  
  25.             acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);  
  26.             // 绑定逻辑处理器  
  27.             acceptor.setHandler(new MinaServerHandler());  
  28.             // 绑定端口  
  29.             acceptor.bind(new InetSocketAddress(BaseConfig.PORT));  
  30.               
  31.             log.info("服务端启动。。。。。端口号为:"+BaseConfig.PORT);  
  32.         } catch (Exception e) {  
  33.             e.printStackTrace();  
  34.         }  
  35.     }  
  36.   
  37. }  

[java] view plain copy
  1. 请注意,过滤器可以使用mina提供的过滤器,也可以自己根据需要编写过滤器。这里我使用的自己编写的过滤器  
[java] view plain copy
  1. 过滤器代码如下  
[java] view plain copy
  1. import org.apache.mina.core.session.IoSession;  
  2. import org.apache.mina.filter.codec.ProtocolCodecFactory;  
  3. import org.apache.mina.filter.codec.ProtocolDecoder;  
  4. import org.apache.mina.filter.codec.ProtocolEncoder;  
  5.   
  6. public class MsgCodecFactory implements ProtocolCodecFactory {  
  7.       
[java] view plain copy
  1. //这里注册自己编写的解码工具  
  2. private final MsgResponseEncoder encoder; // 编码  
  3. private final MsgRequestDecoder decoder; // 解码  
  4.   
  5. public MsgCodecFactory(String charset) {  
  6.     encoder = new MsgResponseEncoder(charset);  
  7.     decoder = new MsgRequestDecoder(charset);  
  8. }  
  9.   
  10. public ProtocolEncoder getEncoder(IoSession session) {  
  11.     return encoder;  
  12. }  
  13.   
  14. public ProtocolDecoder getDecoder(IoSession session) {  
  15.     return decoder;  
  16. }  
[java] view plain copy
  1. 解码代码如下  
[java] view plain copy
  1. import org.apache.log4j.Logger;  
  2. import org.apache.mina.core.buffer.IoBuffer;  
  3. import org.apache.mina.core.session.IoSession;  
  4. import org.apache.mina.filter.codec.CumulativeProtocolDecoder;  
  5. import org.apache.mina.filter.codec.ProtocolDecoderOutput;  
  6.   
  7. import com.chinaums.umscard.util.StringUtils;  
  8.   
  9. public class MsgRequestDecoder extends CumulativeProtocolDecoder {  
  10.     private static final Logger LOGGER = Logger.getLogger(MsgRequestDecoder.class);  
  11.       
  12.     private final String charset;  
  13.   
  14.     public MsgRequestDecoder(String charset) {  
  15.         this.charset = charset;  
  16.     }  
  17.   
  18.     /** 
  19.      *解码器,对传入的iobuffer 进行解码工作,注意顺序是先进先出原则。 
  20.      */  
  21.     @Override  
  22.     protected boolean doDecode(IoSession session, IoBuffer in,  
  23.             ProtocolDecoderOutput out) throws Exception {  
  24.         // TODO Auto-generated method stub  
  25.   
  26.         if (in.remaining() > 2) {  
  27.   
  28.             in.mark();// 标记当前位置,以便reset  
  29.               
  30.             byte[] lenBytes = new byte[3];  
  31.             in.get(lenBytes);  
  32.             int length = Integer.parseInt(StringUtils.hexStr2Str(StringUtils.bytes2HexString(lenBytes)));  
  33. //          int length = StringUtils.bytesToInt(lenBytes);  
  34.               
  35.             if (length > in.remaining()) {// 如果消息内容不够,则重置,相当于不读取size  
  36.                 System.out.println("package notenough  left=" + in.remaining()  
  37.                         + " length=" + length);  
  38.                 in.reset();  
  39.                 return false;// 接收新数据,以拼凑成完整数据  
  40.             } else {  
  41.                 System.out.println("package =" + in.toString());  
  42.                 byte[] bbIn = new byte[length];  
  43.                   
  44.                 in.get(bbIn, 0, length);  
  45.                   
  46.                 byte[] btotal = new byte[length];  
  47.                   
  48.                 System.arraycopy(bbIn, 0, btotal, 0, bbIn.length);  
  49.                   
  50.                 byte[] pwd = new byte[8];  
  51.                   
  52.                 System.arraycopy(btotal, btotal.length-8, pwd, 08);  
  53.                 System.out.println(StringUtils.bytes2HexString(pwd));  
  54.                   
  55.                 String result = StringUtils.bytes2HexString(btotal);  
  56.                 out.write(result);  
  57.                   
  58.                 if (in.remaining() > 0) {// 如果读取内容后还粘了包,就让父类再给一次,进行下一次解析  
  59.                     // System.out.println("package left="+in.remaining()+" data="+in.toString());  
  60.                 }  
  61.                 return true;// 这里有两种情况1:没数据了,那么就结束当前调用,有数据就再次调用  
  62.             }  
  63.         }  
  64.         return false;// 处理成功,让父类进行接收下个包  
  65.     }  
  66.   
  67. }  
[java] view plain copy
  1. import java.nio.charset.Charset;  
[java] view plain copy
  1. import org.apache.mina.core.buffer.IoBuffer;  
  2. import org.apache.mina.core.session.IoSession;  
  3. import org.apache.mina.filter.codec.ProtocolEncoderAdapter;  
  4. import org.apache.mina.filter.codec.ProtocolEncoderOutput;  
[java] view plain copy
  1. public class MsgResponseEncoder extends ProtocolEncoderAdapter {  
  2.    
  3.  private final String charset;  
  4.  public MsgResponseEncoder(String charset) {  
  5.   this.charset = charset;  
  6.  }  
  7.    
  8.  public void encode(IoSession session, Object message,  
  9.    ProtocolEncoderOutput out) throws Exception {  
  10.     
  11.   IoBuffer buf = IoBuffer.allocate(100).setAutoExpand(true);  
  12.   String strOut = message.toString();  
  13. //  buf.putInt(strOut.getBytes(Charset.forName("utf-8")).length);  
  14.   buf.putString(strOut,Charset.forName("GBK").newEncoder());  
  15.   buf.flip();  
  16.   out.write(buf);  
  17.  }  
  18. }  
  19. 以下是业务处理类  
  20.   
  21. import java.util.List;  
  22.   
  23. import org.apache.log4j.Logger;  
  24. import org.apache.mina.core.service.IoHandlerAdapter;  
  25. import org.apache.mina.core.session.IdleStatus;  
  26. import org.apache.mina.core.session.IoSession;  
  27.   
  28. import com.chinaums.umscard.entity.AccountInfo;  
  29. import com.chinaums.umscard.entity.BasCardPos;  
  30. import com.chinaums.umscard.entity.CardMeracc;  
  31. import com.chinaums.umscard.entity.ConsumeParam;  
  32. import com.chinaums.umscard.entity.DataAccReturn;  
  33. import com.chinaums.umscard.entity.DataPosFlow;  
  34. import com.chinaums.umscard.entity.PayTranPay;  
  35. import com.chinaums.umscard.entity.RejectGoodsParam;  
  36. import com.chinaums.umscard.service.AccountInfoService;  
  37. import com.chinaums.umscard.service.CardMeraccService;  
  38. import com.chinaums.umscard.service.ConsumeService;  
  39. import com.chinaums.umscard.service.DataAccReturnService;  
  40. import com.chinaums.umscard.service.DataFlowService;  
  41. import com.chinaums.umscard.service.PosCheckService;  
  42. import com.chinaums.umscard.service.RejectGoodsService;  
  43. import com.chinaums.umscard.service.ReverseService;  
  44. import com.chinaums.umscard.service.impl.AccountInfoServiceImpl;  
  45. import com.chinaums.umscard.service.impl.CardMeraccServiceImpl;  
  46. import com.chinaums.umscard.service.impl.ConsumeServiceImpl;  
  47. import com.chinaums.umscard.service.impl.DataAccReturnServiceImpl;  
  48. import com.chinaums.umscard.service.impl.DataFlowServiceImpl;  
  49. import com.chinaums.umscard.service.impl.PosCheckServiceImpl;  
  50. import com.chinaums.umscard.service.impl.RejectGoodsServiceImpl;  
  51. import com.chinaums.umscard.service.impl.ReverseServiceImpl;  
  52. import com.chinaums.umscard.util.MySecurityUtil;  
  53. import com.chinaums.umscard.util.StringUtils;  
  54. import com.chinaums.umscard.util.XorUtil;  
  55.   
  56. public class MinaServerHandler extends IoHandlerAdapter {  
  57.       
  58.     public static final Logger log = Logger.getLogger(MinaServerHandler.class);  
  59.       
  60.     @Override  
  61.     public void sessionCreated(IoSession session) throws Exception {  
  62.         log.info("服务端与客户端创建连接...");  
  63.     }  
  64.       
  65.     @Override  
  66.     public void sessionOpened(IoSession session) throws Exception {  
  67.         log.info("服务端与客户端打开连接");  
  68.     }  
  69.       
  70.     @Override  
  71.     public void sessionClosed(IoSession session) throws Exception {  
  72.         log.info("服务端与客户端关闭连接");  
  73.     }  
  74.       
[java] view plain copy
  1.     //这个方法用于接收监听接收到的报文数据,以进行相关的业务处理  
  2.     @Override  
  3.     public void messageReceived(IoSession session, Object message) throws Exception{  
  4.           
  5.         String m = message.toString();  
  6.           
  7.         String bcd = m.substring(m.length()-16);  
  8.           
  9. //      System.out.println(bcd);  
  10.           
  11.         byte[] bt = message.toString().getBytes();  
  12.           
  13.         byte[] keypwdbt = new byte[8];  
  14.           
  15.         System.arraycopy(bt, bt.length-8, keypwdbt, 08);  
  16.           
  17.         String result = MySecurityUtil.bcd2Str(keypwdbt);  
  18.           
  19.         String msg = StringUtils.hexStr2Str(message.toString());  
  20.           
  21. //      PosCheckService posService = new PosCheckServiceImpl();  
  22.           
  23.         PosCheckService posCheckService = new PosCheckServiceImpl();  
  24.           
  25.         DataFlowService dataFlowService = new DataFlowServiceImpl();  
  26.           
  27.         MySecurityUtil ms = new MySecurityUtil();  
  28.           
  29. //      PosCheckService posService = new PosCheckServiceImpl();  
  30.           
  31.         if(msg != null){  
  32.             String msgArr = msg.replace("|"",");  
  33.             String[] posArr = msgArr.split(",");  
  34.               
  35.             if(msg.toString().startsWith("0001")){  
  36.                 String checkmsg = "";//用于接收签到结果  
  37.                   
  38.                 String posno = posArr[1];  
  39.                   
  40.                 String key = posArr[2];  
  41.                   
  42.                 String keypwd = posArr[3];//异或加密后的验证码  
  43.                   
  44.                 StringBuffer sb = new StringBuffer();  
  45.                   
  46.                 sb.append(posArr[0]);  
  47.                 sb.append("|");  
  48.                   
  49.                 //以下将报文进行异或加密处理(不取最后一个元素)  
  50.                 for(int i=1;i<posArr.length-1;i++){  
  51.                     sb.append(posArr[i]+",");  
  52.                 }  
  53.                   
  54.                 System.out.println(sb);  
  55.                 //异或运算  
  56.                 byte[] b = XorUtil.xorChar(sb.toString().toCharArray());  
  57.                   
  58.                 //加密  
  59.                 byte[] key1 = MySecurityUtil.hexStr2Str(key.substring(0, key.length()/2)).getBytes();  
  60.                 byte[] key2 = MySecurityUtil.hexStr2Str(key.substring(key.length()/2)).getBytes();  
  61.                   
  62.                 byte[] p = ms.TripleDesEncrypt(b, key1, key2);  
  63.                   
  64.                 //转成字符串  
  65.                 String s = MySecurityUtil.bcd2Str(p);  
  66.                   
  67.                 BasCardPos basCardPos = posCheckService.checkPos(posno);  
  68.                   
  69.                 if(basCardPos != null && basCardPos.getIkey().equals(posArr[2])){  
  70.                     checkmsg = "00";//签到成功  
  71.                 }else if(basCardPos != null && basCardPos.getIkey() != posArr[2]){  
  72.                     checkmsg = "99";//密钥验证失败  
  73.                 }else{  
  74.                     checkmsg = "01";//签到失败  
  75.                 }  
  76.                   
  77.                 //插入日志  
  78.                 DataPosFlow dataPosFlow = new DataPosFlow();  
  79.                 dataPosFlow.setPosno(posno);  
  80.                 dataPosFlow.setVreturn(checkmsg);  
  81.                   
  82.                 dataFlowService.PosCheckDataFlow(dataPosFlow);  
  83.                   
  84.                 session.write(checkmsg+"#"+s);  
  85.                 log.info(checkmsg);  
  86.             }else if(msg.toString().startsWith("0002")){  
  87.   
  88.                 AccountInfoService accService = new AccountInfoServiceImpl();  
  89.                   
  90.                 String selectmsg = "";//用于接收查询账户返回的状态码  
  91.                   
  92.                 //取磁道内容  
  93.                 String cardnoecp = posArr[1];  
  94.                 //取终端号  
  95.                 String posno = posArr[2];  
  96.                 //获取密钥  
  97.                 String key = posArr[3];  
  98.                 //获取密码  
  99.                 String pwd = posArr[4];  
  100.                 //第一步检查终端的合法性  
  101.                 BasCardPos bcp = posCheckService.checkPos(posno);  
  102.                   
  103.                 StringBuffer sb = new StringBuffer();  
  104.                   
  105.                 if(bcp != null && bcp.getIkey().equals(key)){  
  106.                   
  107.                     List<AccountInfo> accList = accService.checkAccount(cardnoecp);  
  108.                       
  109.                     DataPosFlow dataPosFlow = null;  
  110.                       
  111.                     if(accList != null && accList.size() != 0){  
  112.                         selectmsg = "00";//查询成功  
  113.                         sb.append(selectmsg+"#");  
  114.                         for(AccountInfo account : accList){  
  115. //                          String hexAccountName = new String(account.getAccname().getBytes("UTF-8"), "GB18030");  
  116.                             sb.append(account.getCardid()+","+account.getCardno()+","  
  117.                             +account.getAccid()+","+account.getAccname()+","+account.getBalance()+"|");  
  118.                               
  119.                             dataPosFlow = new DataPosFlow();  
  120.                               
  121.                             dataPosFlow.setCardid(account.getCardid());  
  122.                             dataPosFlow.setAccid(account.getAccid());  
  123.                             dataPosFlow.setPosno(posno);  
  124.                             dataPosFlow.setVreturn(selectmsg);  
  125.                               
  126.                             dataFlowService.AccountInfoDataFlow(dataPosFlow, account);  
  127.                         }  
  128.                         session.write(sb);  
  129.                     }else{  
  130.                         selectmsg = "98";  
  131.                         session.write(selectmsg+"#");  
  132.                     }  
  133.                 }else if(bcp != null && !key.equals(bcp.getIkey())){  
  134.                     selectmsg = "99";  
  135.                     session.write(selectmsg+"#");  
  136.                 }  
  137.                 log.info(selectmsg);  
  138.             }else if(msg.toString().startsWith("0003")){  
  139.   
  140.                 ConsumeService consumeService = new ConsumeServiceImpl();  
  141.                   
  142.                 String consumemsg = "";  
  143.                   
  144.                 //获取cardid  
  145.                 String cardid = posArr[1];  
  146.                 //获取accid  
  147.                 String accid = posArr[2];  
  148.                   
  149.                 String trantype = posArr[3];  
  150.                   
  151.                 String amt = posArr[4];  
  152.                   
  153.                 //获取终端号  
  154.                 String posno = posArr[5];  
  155.                   
  156.                 //获取密钥  
  157.                 String key = posArr[6];  
  158.                   
  159.                 String pwd = posArr[7];  
  160.                   
  161.                 String possno = posArr[8];  
  162.                   
  163. //              String field1 = posArr[8];  
  164.                   
  165.                 ConsumeParam param = new ConsumeParam();  
  166.                 param.setCardid(Float.parseFloat(cardid));  
  167.                 param.setAccid(3f);  
  168.                 param.setAmt(Float.parseFloat(amt)/100);  
  169.                 param.setPosno(posno);  
  170.                 param.setPossno(possno);  
  171.                 param.setTrainType(Float.parseFloat(trantype));  
  172.                   
  173.                 BasCardPos bcp = posCheckService.checkPos(posno);  
  174.                   
  175.                 //终端验证成功,验证卡是否可以在终端上使用  
  176.                 if(bcp != null && key.equals(bcp.getIkey())){  
  177.                     int count = consumeService.poscount(Integer.parseInt(cardid), Integer.parseInt(accid));  
  178.                       
  179.                     //count不为0说明卡片可以在终端上使用  
  180.                     if(count != 0){  
  181.                         consumemsg = consumeService.consume(param);  
  182.                     }else if(key != bcp.getIkey()){  
  183.                         consumemsg = "99";//密钥验证失败  
  184.                     }else if(count == 0){  
  185.                         consumemsg = "98";//不存在卡  
  186.                     }else{  
  187.                         consumemsg = "97";//密码错误  
  188.                     }  
  189.                 }  
  190.                 session.write(consumemsg+"#");  
  191.                 log.info(consumemsg);  
  192.             }else if(msg.toString().startsWith("0004")){  
  193.   
  194.                   
  195.                 String rejectmsg = "";  
  196.                   
  197.                 String cardid = posArr[1];  
  198.                   
  199.                 String rejectTranType = posArr[2];  
  200.                   
  201.                 String rejectPosno = posArr[3];  
  202.                   
  203.                 String rejectkey = posArr[4];  
  204.                   
  205.                 String rejectpwd = posArr[5];  
  206.                   
  207.                 String rejectTranId = posArr[6];  
  208.                   
  209.                 RejectGoodsParam param = new RejectGoodsParam();  
  210.                   
  211.                 param.setCardid(Integer.parseInt(cardid));  
  212.                 param.setKey(rejectkey);  
  213.                 param.setPosno(rejectPosno);  
  214.                 param.setPwd(rejectpwd);  
  215.                 param.setTranid(rejectTranId);  
  216.                 param.setTranType(Integer.parseInt(rejectTranType));//退货  
  217.                   
  218.                 BasCardPos bcp = posCheckService.checkPos(rejectPosno);  
  219.                   
  220.                 RejectGoodsService rgService = new RejectGoodsServiceImpl();  
  221.                   
  222.                 DataAccReturnService dataAccReturnService = new DataAccReturnServiceImpl();  
  223.                   
  224.                 if(bcp != null && rejectkey.equals(bcp.getIkey())){  
  225.                     //根据传入的信息查询用户的卡信息和原单号,以便验证交易信息是否属实  
  226.                     //验证成功,查询账户信息,返回账户信息  
  227.                     rejectmsg = rgService.rejectGoods(param);  
  228.                       
  229.                     //交易信息存在返回00向退货申请表中写入退货申请  
  230.                     if (rejectmsg.equals("00")) {  
  231.                         //查询交易记录  
  232.                         PayTranPay pay = rgService.getPayTranPay(param);  
  233.                         //验证成功将退货请求写入退货请求表  
  234.                         DataAccReturn dataAccReturn = new DataAccReturn();  
  235.                         dataAccReturn.setCashierno(rejectPosno);  
  236.                         dataAccReturn.setTranid(rejectTranId);  
  237.                         dataAccReturn.setPosno(rejectPosno);  
  238.                         dataAccReturn.setCardid(Integer.parseInt(cardid));  
  239.                         dataAccReturn.setAccid(Integer.parseInt(pay.getPaysubtype()));  
  240.                         dataAccReturn.setAmt(pay.getAmt());  
  241.                         dataAccReturn.setPosno(rejectPosno);  
  242.                         dataAccReturnService.addDataAccReturn(dataAccReturn);  
  243.                     }  
  244.                       
  245.                 }else if(bcp != null && !rejectkey.equals(bcp.getIkey())){  
  246.                     rejectmsg = "99";  
  247.                 }else{  
  248.                     rejectmsg = "97";  
  249.                 }  
  250.                   
  251.                 CardMeraccService cardMeraccService = new CardMeraccServiceImpl();  
  252.                   
  253.                 CardMeracc cardm = cardMeraccService.getCardMeraccByCardId(Integer.parseInt(cardid));  
  254.                   
  255.                 DataPosFlow dataPosFlow = new DataPosFlow();  
  256.                   
  257.                 dataPosFlow.setCardid(Integer.parseInt(cardid));  
  258.                 dataPosFlow.setPosno(rejectPosno);  
  259.                 dataPosFlow.setVreturn(rejectmsg);  
  260.                   
  261.                 //写入日志  
  262.                 dataFlowService.RejectGoodsDataPosFlow(dataPosFlow, cardm);  
  263.                 session.write(rejectmsg+"#");  
  264.             }else if(msg.toString().startsWith("0005")){  
  265.                   
  266.                 String reveremsg = "";  
  267.                   
  268.                 //pos终端号  
  269.                 String posno = posArr[1];  
  270.                   
  271.                 //密钥  
  272.                 String key = posArr[2];  
  273.                   
  274.                 //批次号(POS终端生成)  
  275.                 String posSno = posArr[3];  
  276.                   
  277.                 //预留字段  
  278. //              String field1 = posArr[4];  
  279.                   
  280.                 ReverseService reverserService = new ReverseServiceImpl();  
  281.                   
  282.                 reveremsg = reverserService.reverse(posSno, posno);  
  283.                   
  284.                 session.write(reveremsg+"#");  
  285.             }  
  286.         }  
  287.           
  288.         log.info("服务端收到的数据为:"+message);  
  289.     }  
  290.       
  291.     @Override  
  292.     public void messageSent(IoSession session, Object message) throws Exception {  
  293.         log.info("服务端发送消息成功!");  
  294.     }  
  295.       
  296.     @Override  
  297.     public void sessionIdle(IoSession session, IdleStatus status) throws Exception {  
  298.         log.info("服务端进入空闲状态...");  
  299.     }  
  300.       
  301.     @Override  
  302.     public void exceptionCaught(IoSession session, Throwable cause) throws Exception {  
  303.         log.error("服务端发送异常...", cause);  
  304.     }  
  305.       
  306.       
  307. }  
至此服务端代码编写完毕,下面给一段客户端的代码。一般我们测试时用TCPUDP测试工具进行测试,不必要编写客户端程序,为了让大家有个参考,这里我把代码贴出来,只是简单的客户端程序,代码如下
[java] view plain copy
  1. import java.net.InetAddress;  
  2. import java.net.InetSocketAddress;  
  3. import java.net.UnknownHostException;  
  4. import java.nio.charset.Charset;  
  5.   
  6. import org.apache.log4j.Logger;  
  7. import org.apache.mina.core.future.ConnectFuture;  
  8. import org.apache.mina.core.service.IoConnector;  
  9. import org.apache.mina.core.session.IoSession;  
  10. import org.apache.mina.filter.codec.ProtocolCodecFilter;  
  11. import org.apache.mina.filter.codec.textline.LineDelimiter;  
  12. import org.apache.mina.filter.codec.textline.TextLineCodecFactory;  
  13. import org.apache.mina.transport.socket.nio.NioSocketConnector;  
  14.   
  15. public class MinaClient {  
  16.       
  17.     private static final Logger logger = Logger.getLogger(MinaClient.class);  
  18.       
  19. //  private static String ip = address.get  
  20.       
  21.     public static void main(String[] args) throws UnknownHostException {  
  22.         InetAddress address = InetAddress.getLocalHost();  
  23.           
  24.         String ip = address.getHostAddress().toString();  
  25.           
  26.         // 创建一个非阻塞的客户端程序  
  27.         IoConnector connector = new NioSocketConnector();  
  28.         // 设置链接超时时间  
  29.         connector.setConnectTimeout(30000);  
  30.           
  31.         // 添加过滤器  
  32.         connector.getFilterChain().addLast(  
  33.                 "codec",  
  34.                 new ProtocolCodecFilter(new TextLineCodecFactory(Charset  
  35.                         .forName("UTF-8"), LineDelimiter.WINDOWS.getValue(),  
  36.                         LineDelimiter.WINDOWS.getValue())));  
  37.         // 添加业务逻辑处理器类  
  38.         connector.setHandler(new MinaClientHandler());  
  39.           
  40.         IoSession session = null;  
  41.         try {  
  42.             ConnectFuture future = connector.connect(new InetSocketAddress(  
  43.                     ip, 2000));// 创建连接  
  44.             future.awaitUninterruptibly();// 等待连接创建完成  
  45.             session = future.getSession();// 获得session  
  46.               
  47. //          Scanner s = new Scanner(System.in);  
  48.               
  49. //          String msg = s.next();  
  50.               
  51.               
  52.             session.write("0001|10003,44444444444444444444444444444444,null");// 发送消息  
  53.   
  54.             session.write("quit");//发送后与服务端断开连接  
  55.         } catch (Exception e) {  
  56.             logger.error("客户端链接异常...", e);  
  57.         }  
  58.           
  59.           
  60. //      session.getCloseFuture().awaitUninterruptibly();//等待连接断开  
  61.         connector.dispose();  
  62.     }  
  63.   
  64. }  
编写客户端监听业务处理Handler类
[java] view plain copy
  1. import org.apache.log4j.Logger;  
  2. import org.apache.mina.core.service.IoHandlerAdapter;  
  3. import org.apache.mina.core.session.IoSession;  
  4.   
  5. public class MinaClientHandler extends IoHandlerAdapter {  
  6.   
  7.     private static Logger logger = Logger.getLogger(MinaClientHandler.class);  
  8.   
  9.     @Override  
  10.     public void messageReceived(IoSession session, Object message)  
  11.             throws Exception {  
  12.         String msg = message.toString();  
  13.         logger.info("客户端接收到的信息为:" + msg);  
  14.     }  
  15.   
  16.     @Override  
  17.     public void exceptionCaught(IoSession session, Throwable cause)  
  18.             throws Exception {  
  19.         logger.error("客户端发生异常...", cause);  
  20.     }  
  21.   
  22. }  
0 0
原创粉丝点击