mina现在用的很多了,之前也有用到,但是毕竟不熟悉,于是查了一些资料,做了一些总结。看代码是最直观的,比什么长篇大论都要好。不过其中重要的理论,也要理解下。

首先是环境,程序运行需要几个包,这里用maven比较方便。

pom.xml:

  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  3. <modelVersion>4.0.0</modelVersion>
  4.  
  5. <groupId>MyMinaServer</groupId>
  6. <artifactId>mina</artifactId>
  7. <version>0.0.1-SNAPSHOT</version>
  8. <packaging>jar</packaging>
  9.  
  10. <name>mina</name>
  11. <url>http://maven.apache.org</url>
  12.  
  13. <properties>
  14. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  15. </properties>
  16.  
  17. <dependencies>
  18. <dependency>
  19. <groupId>org.apache.mina</groupId>
  20. <artifactId>mina-core</artifactId>
  21. <version>2.0.4</version>
  22. </dependency>
  23.  
  24. <dependency>
  25. <groupId>org.slf4j</groupId>
  26. <artifactId>jcl-over-slf4j</artifactId>
  27. <version>1.6.1</version>
  28. </dependency>
  29.  
  30. <dependency>
  31. <groupId>org.slf4j</groupId>
  32. <artifactId>slf4j-nop</artifactId>
  33. <version>1.6.1</version>
  34. </dependency>
  35. <dependency>
  36. <groupId>junit</groupId>
  37. <artifactId>junit</artifactId>
  38. <version>3.8.1</version>
  39. <scope>test</scope>
  40. </dependency>
  41. </dependencies>
  42. </project>

然后就可以写代码了。

---------------------------------------------------------- 分割线 -----------------------------------------------------------------------------------------

一,简单的客户端和服务端程序

服务端程序:

  1. package MyMinaServer.mina;
  2.  
  3. import java.io.IOException;
  4. import java.net.InetSocketAddress;
  5. import java.nio.charset.Charset;
  6.  
  7. import org.apache.mina.core.service.IoAcceptor;
  8. import org.apache.mina.core.session.IdleStatus;
  9. import org.apache.mina.filter.codec.ProtocolCodecFilter;
  10. import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
  11. import org.apache.mina.filter.logging.LoggingFilter;
  12. import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
  13.  
  14. public class MainServer {
  15. private static final int Port=8888;
  16. public static void main(String[] args) {
  17. IoAcceptor ioAcceptor=new NioSocketAcceptor();
  18. System.out.println("begin server....");
  19. ioAcceptor.getFilterChain().addLast("logger", new LoggingFilter());
  20. ioAcceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
  21. ioAcceptor.setHandler(new HelloWorldHandler());
  22. ioAcceptor.getSessionConfig().setReadBufferSize(2048);
  23. ioAcceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
  24. try {
  25. ioAcceptor.bind(new InetSocketAddress(Port));
  26. } catch (IOException e) {
  27. // TODO Auto-generated catch block
  28. e.printStackTrace();
  29. }
  30. }
  31. }

服务端,创建连接,然后这里注册了几个过滤链,这里简单写了需要的两个,到后面的内容中还可以加入一个加密的ssl链。

其中重要的是setHandler这个,在这个里面,我们可以定义自己的handler,然后做自己的业务。下面有这个handler的简单代码。

最后设置session的缓冲,和idle(空闲处理)的设定,再为此连接绑定一个端口。

其中需要注意的是,在服务端和客户端的代码里面,如果要传递string信息,codec编码过滤器中,要这么写:new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8")))。否则报错。

业务处理的handler:

  1. package MyMinaServer.mina;
  2.  
  3. import org.apache.mina.core.service.IoHandlerAdapter;
  4. import org.apache.mina.core.session.IdleStatus;
  5. import org.apache.mina.core.session.IoSession;
  6.  
  7. public class HelloWorldHandler extends IoHandlerAdapter{
  8.  
  9. @Override
  10. public void exceptionCaught(IoSession session, Throwable cause)
  11. throws Exception {
  12. // TODO Auto-generated method stub
  13. super.exceptionCaught(session, cause);
  14. }
  15.  
  16. @Override
  17. public void messageReceived(IoSession session, Object message)
  18. throws Exception {
  19. // TODO Auto-generated method stub
  20. String string=message.toString();
  21. if (string.trim().equalsIgnoreCase("quit")) {
  22. session.close(true);
  23. return;
  24. }
  25. System.out.println("recevied message:"+string);
  26. String reply=" hi, i am server";
  27. session.write(reply);
  28. System.out.println("message have been written");
  29. }
  30.  
  31. @Override
  32. public void messageSent(IoSession session, Object message) throws Exception {
  33. // TODO Auto-generated method stub
  34. System.out.println("message have been sent");
  35. }
  36.  
  37. @Override
  38. public void sessionClosed(IoSession session) throws Exception {
  39. // TODO Auto-generated method stub
  40. System.out.println("closed session");
  41. }
  42.  
  43. @Override
  44. public void sessionCreated(IoSession session) throws Exception {
  45. // TODO Auto-generated method stub
  46. System.out.println("session created");
  47. }
  48.  
  49. @Override
  50. public void sessionIdle(IoSession session, IdleStatus status)
  51. throws Exception {
  52. // TODO Auto-generated method stub
  53. System.out.println("IDLE "+session.getIdleCount(status));
  54. }
  55.  
  56. @Override
  57. public void sessionOpened(IoSession session) throws Exception {
  58. // TODO Auto-generated method stub
  59. System.out.println("session opened");
  60. }
  61.  
  62. }

这里的每个方法,算是事件。在每个事件中,我们可以定义自己的处理。在前面的《AndroidPn源码分析(一)》这篇文章中,笔者曾写过他们的每个事件代表的含义,不过从字面意思也很好理解。

这里主要是对接受到信息的处理,如果不是收到quit字符,则返回给客户端一句 hi,i am server。

服务端暂时到此,以下是客户端。

  1. package com.example.mina.server;
  2.  
  3. import java.net.InetSocketAddress;
  4. import java.nio.charset.Charset;
  5.  
  6. import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
  7. import org.apache.mina.core.future.CloseFuture;
  8. import org.apache.mina.core.future.ConnectFuture;
  9. import org.apache.mina.core.session.IoSession;
  10. import org.apache.mina.filter.codec.ProtocolCodecFilter;
  11. import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
  12. import org.apache.mina.filter.logging.LoggingFilter;import org.apache.mina.transport.socket.SocketConnector;
  13. import org.apache.mina.transport.socket.nio.NioSocketConnector;
  14.  
  15. import com.example.mina.charset.CharsetFactory;
  16. import com.example.mina.hanlder.MsgHanler;public class MinaClient {
  17.  
  18. private SocketConnector connector;
  19. private ConnectFuture future;
  20. private IoSession session;
  21.  
  22. public boolean connect() {
  23. /*
  24. * 1.创建一个socket连接,连接到服务器
  25. */
  26. connector = new NioSocketConnector();
  27.  
  28. /*
  29. * 获取过滤器链,用于添加过滤器
  30. */
  31. DefaultIoFilterChainBuilder chain = connector.getFilterChain();
  32.  
  33. // b.添加日志过滤器
  34. chain.addLast("logger", new LoggingFilter());
  35.  
  36. // c.添加字符的编码过滤器
  37. chain.addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
  38.  
  39. /*
  40. * 3.设置消息处理器,用于处理接收到的消息
  41. */
  42. connector.setHandler(new MsgHanler());
  43.  
  44. /*
  45. * 4.根据IP和端口号连接到服务器
  46. */
  47. future = connector.connect(new InetSocketAddress("127.0.0.1", 8888));
  48. // 等待连接创建完成
  49. future.awaitUninterruptibly();
  50.  
  51. /*
  52. * 5.获取session对象,通过session可以向服务器发送消息;
  53. */
  54. session = future.getSession();
  55. session.getConfig().setUseReadOperation(true);
  56. return future.isConnected();
  57. }
  58.  
  59. /**
  60. * 往服务器发送消息
  61. *
  62. * @param message
  63. */
  64. public void sendMsg2Server(String message) {
  65. session.write(message);
  66. }
  67.  
  68. /**
  69. * 关闭与服务器的连接
  70. *
  71. * @return
  72. */
  73. public boolean close() {
  74. CloseFuture future = session.getCloseFuture();
  75. future.awaitUninterruptibly(1000);
  76. connector.dispose();
  77. return true;
  78. }
  79. }

然后同样是一个客户端的handler,和server的很像:

  1. package com.example.mina.hanlder;
  2.  
  3. import org.apache.mina.core.service.IoHandlerAdapter;
  4. import org.apache.mina.core.session.IoSession;
  5. import org.slf4j.Logger;
  6. import org.slf4j.LoggerFactory;
  7.  
  8. public class MsgHanler extends IoHandlerAdapter {
  9. private static final Logger log = LoggerFactory.getLogger(MsgHanler.class);
  10.  
  11. @Override
  12. public void exceptionCaught(IoSession session, Throwable cause)
  13. throws Exception {
  14. // 出现异常
  15. log.error("--------exception--------");
  16. super.exceptionCaught(session, cause);
  17. }
  18.  
  19. @Override
  20. public void messageReceived(IoSession session, Object message)
  21. throws Exception {
  22. // 从服务器中接收到消息后的处理
  23. log.info("--------msg receive--------");
  24. log.info("Message:{}" + message.toString());
  25. super.messageReceived(session, message);
  26. }
  27.  
  28. @Override
  29. public void messageSent(IoSession session, Object message) throws Exception {
  30. // 往服务器中发送消息
  31. log.info("--------msg sent--------");
  32. super.messageSent(session, message);
  33. }
  34.  
  35. @Override
  36. public void sessionCreated(IoSession session) throws Exception {
  37. // 当session被创建的时候调用
  38. log.info("--------session create--------");
  39. super.sessionCreated(session);
  40. }
  41. }

写一个入口方法:

  1. package com.example.mina.server;
  2.  
  3. public class Main {
  4.  
  5. public static void main(String[] args) {
  6. MinaClient client=new MinaClient();
  7. client.connect();
  8. client.sendMsg2Server("message from cilent");
  9. }
  10. }

这样,客户端就可以工作了。

先启动服务端,然后启动客户端,就可以看到在两个控制台中,分别有交互信息。

服务端:

begin server....
session created
session opened
recevied message:message from cilent
message have been written
message have been sent

客户端:

[QC] INFO [NioProcessor-2] org.apache.mina.filter.logging.LoggingFilter.log(186) | CREATED
[QC] INFO [NioProcessor-2] com.example.mina.hanlder.MsgHanler.sessionCreated(54) | --------session create--------
[QC] INFO [NioProcessor-2] org.apache.mina.filter.logging.LoggingFilter.log(186) | OPENED
[QC] INFO [NioProcessor-2] org.apache.mina.filter.logging.LoggingFilter.log(157) | SENT: HeapBuffer[pos=0 lim=0 cap=0: empty]
[QC] INFO [NioProcessor-2] com.example.mina.hanlder.MsgHanler.messageSent(47) | --------msg sent--------
[QC] INFO [NioProcessor-2] org.apache.mina.filter.logging.LoggingFilter.log(157) | RECEIVED: HeapBuffer[pos=0 lim=17 cap=2048: 20 68 69 2C 20 69 20 61 6D 20 73 65 72 76 65 72...]
[QC] INFO [NioProcessor-2] com.example.mina.hanlder.MsgHanler.messageReceived(39) | --------msg receive--------
[QC] INFO [NioProcessor-2] com.example.mina.hanlder.MsgHanler.messageReceived(40) | Message:{} hi, i am server

客户端因为用了log4j,打印比较多信息。

到此,这个例子就完成了。

Mina入门实例(一)的更多相关文章

  1. Apache Mina入门实例

    一.mina是啥 ApacheMINA是一个网络应用程序框架,用来帮助用户简单地开发高性能和高可扩展性的网络应用程序.它提供了一个通过Java NIO在不同的传输例如TCP/IP和UDP/IP上抽象的 ...

  2. Apache Mina 入门实例

    这个教程是介绍使用Mina搭建基础示例.这个教程内容是以创建一个时间服务器. 以下是这个教程需要准备的东西: MINA 2.0.7 Core JDK 1.5 或更高 SLF4J 1.3.0 或更高 L ...

  3. Mina入门实例

    继续上一篇,这篇主要讲通过mina往B端发送消息.并接受消息,mina是一个网络通信框架,封装了javaNIO.简单易用.网上有非常多关于他的介绍,在此不赘述了. 如上篇所介绍,完毕功能,须要五个类: ...

  4. JAVA通信系列二:mina入门总结

    一.学习资料 Mina入门实例(一) http://www.cnblogs.com/juepei/p/3939119.html Mina入门教程(二)----Spring4 集成Mina http:/ ...

  5. React 入门实例教程(转载)

    本人转载自: React 入门实例教程

  6. struts入门实例

    入门实例 1  .下载struts-2.3.16.3-all  .不摆了.看哈就会下载了. 2  . 解压  后 找到 apps 文件夹. 3.    打开后将 struts2-blank.war   ...

  7. Vue.js2.0从入门到放弃---入门实例

    最近,vue.js越来越火.在这样的大浪潮下,我也开始进入vue的学习行列中,在网上也搜了很多教程,按着教程来做,也总会出现这样那样的问题(坑啊,由于网上那些教程都是Vue.js 1.x版本的,现在用 ...

  8. wxPython中文教程入门实例

    这篇文章主要为大家分享下python编程中有关wxPython的中文教程,分享一些wxPython入门实例,有需要的朋友参考下     wxPython中文教程入门实例 wx.Window 是一个基类 ...

  9. Omnet++ 4.0 入门实例教程

    http://blog.sina.com.cn/s/blog_8a2bb17d01018npf.html 在网上找到的一个讲解omnet++的实例, 是4.0下面实现的. 我在4.2上试了试,可以用. ...

随机推荐

  1. llinux常用命令

    (1)Ctrl+alt+(1-6)可调用控制台程序 (2)date---可看时间日期 (3)date 月日时分年 ------可修改时间 (4)useradd-------新建用户 (5)passwd ...

  2. SOUI Editor使用教程

    感谢网友"指尖"为SOUI开发的UiEditor, 目前该UI编辑器已经基本可用, 源代码在soui svn demos\uieditor. 下面是"指尖"提供 ...

  3. C++产生随机数

    随机数 计算机的随机数都是由伪随机数,即是由小M多项式序列生成的,其中产生每个小序列都有一个初始值,即随机种子.(注意: 小M多项式序列的周期是65535,即每次利用一个随机种子生成的随机数的周期是6 ...

  4. PowerDesigner导出SQL脚本

    1. 先创建E-R图模型

  5. python调用c\c++

    前言 python 这门语言,凭借着其极高的易学易用易读性和丰富的扩展带来的学习友好性和项目友好性,近年来迅速成为了越来越多的人们的首选.然而一旦拿python与传统的编程语言(C/C++)如来比较的 ...

  6. 编写高质量的 Java 代码

    代码质量概述 代码质量所涉及的5个方面,编码标准.代码重复.代码覆盖率.依赖项分析.复杂度分析.这5方面很大程序上决定了一份代码的质量高低. 我们分别来看一下这5方面:编码标准:这个想必都很清楚,每个 ...

  7. npm 基础

    npm账户 npm adduser npm whoami 初始化项目: npm init --scope=<username> 项目必要文件 README.md pageage.json: ...

  8. 浩瀚PDA开单器-结束手工开单模式【百货、商超】PDA安卓智能手持POS 进销存管理系统移动收银管理软件

    移动销售终端:先进的跨平台技术,支持智能PDA等移动终端提供移动销售开单.移动POS.移动查询货品.移动盘点等功能. 移动开单器的操作说明 第一步:选客户 Ø        用户在空白开单主页左划屏幕 ...

  9. 并查集+树链剖分+线段树 HDOJ 5458 Stability(稳定性)

    题目链接 题意: 有n个点m条边的无向图,有环还有重边,a到b的稳定性的定义是有多少条边,单独删去会使a和b不连通.有两种操作: 1. 删去a到b的一条边 2. 询问a到b的稳定性 思路: 首先删边考 ...

  10. Idea 实时编译 和 热部署

    实时编译 idea自动保存编写好的文件,但是不会编译,想要编译需要按ctrl+F9(编译整个项目)ctrl+shift+f9(单个文件),不仅麻烦而且和平常习惯也不相复合.怎么令idea的ctrl+s ...