开发者社区> 凌浩雨> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

Java Mina-2.0.16框架学习使用

简介: 本文使用mina-2.0.16.jar Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP、UDP/IP协议栈的通信框架(当然,也可以提供JAVA 对象的序列化服务、虚拟机管道通信服务等),Mina 可以帮助我们快速开发高性能、高扩展性的网络通信应用,Mina 提供了事件驱动、异步(Mina 的异步IO 默认使用的是JAVA NIO 作为底层支持)操作的编程模型。
+关注继续查看

本文使用mina-2.0.16.jar

Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP、UDP/IP协议栈的通信框架(当然,也可以提供JAVA 对象的序列化服务、虚拟机管道通信服务等),Mina 可以帮助我们快速开发高性能、高扩展性的网络通信应用,Mina 提供了事件驱动、异步(Mina 的异步IO 默认使用的是JAVA NIO 作为底层支持)操作的编程模型。
Mina 同时提供了网络通信的Server 端、Client 端的封装,无论是哪端,Mina 在整个网通通信结构中都处于如下的位置:可见Mina 的API 将真正的网络通信与我们的应用程序隔离开来,你只需要关心你要发送、接收的数据以及你的业务逻辑即可。同样的,无论是哪端,Mina 的执行流程如下所示:
(1) IoService:这个接口在一个线程上负责套接字的建立,拥有自己的Selector,监听是否有连接被建立。
(2) IoProcessor:这个接口在另一个线程上,负责检查是否有数据在通道上读写,也就是说它也拥有自己的Selector,这是与我们使用Java NIO 编码时的一个不同之处,通常在JavaNIO 编码中,我们都是使用一个Selector,也就是不区分IoService与IoProcessor 两个功能接口。另外,IoProcessor 负责调用注册在IoService 上的过滤器,并在过滤器链之后调用IoHandler。
(3) IoFilter:这个接口定义一组拦截器,这些拦截器可以包括日志输出、黑名单过滤、数据的编码(write 方向)与解码(read 方向)等功能,其中数据的encode 与decode是最为重要的、也是你在使用Mina 时最主要关注的地方。
(4) IoHandler:这个接口负责编写业务逻辑,也就是接收、发送数据的地方。

  1. 服务器端

/**
 * mina服务器端
 * @author mazaiting
 */
public class MinaServer {
    /**
     * 监听的端口
     */
    private static final int PORT = 9123;
    
    public static void start() throws IOException{
        // 1. 创建IoAcceptor
        IoAcceptor acceptor = new NioSocketAcceptor();
        // 2. 加入日志记录过滤器,用SL4J库记录信息
        acceptor.getFilterChain().addLast("logger", new LoggingFilter());
        // 3. 加入编码过滤器,用于解码所有收到的信息,使用 new TextLineCodecFactory() r
        // 发送的信息进行编码,返回是MINA自带的,功能有限,只能处理文本戒者String类型。
        acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(
                new TextLineCodecFactory(Charset.forName("UTF-8"))));
        // 4. 设置ServerHandler, 自定义的Handler,TimeServerHandler
        acceptor.setHandler(new TimerServerHandler());
        // 5. 设置Session的对应I/O processor读缓存区大小2048,通常这个参数不需要设置
        acceptor.getSessionConfig().setReadBufferSize(2048);
        // 6. 设置空闲时间, 这里的BOTH_IDLE指EADER_IDLE和WRITER_IDLE都为10秒
        acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
        // 7. 绑定监听端口9123.
//      acceptor.bind(new InetSocketAddress("localhost",PORT));
        acceptor.bind(new InetSocketAddress(PORT)); 
    }
    
    public static void main(String[] args) throws IOException {
        start();
    }
    
    /**
     * 服务器端消息处理器
     * @author mazaiting
     */
    public static class TimerServerHandler extends IoHandlerAdapter{
        @Override
        public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
            /**
             * 自定义异常处理, 要不然异常会被“吃掉”;
             */
            cause.printStackTrace();
        }
        @Override
        public void messageReceived(IoSession session, Object message) throws Exception {
            /**
             * 对接收到的消息(已经解码)迕行下一步处理,这里对收到的字符串进行判断,
             * 如果是”quit”则断开连接;否则输出当前时间的字符串格式;
             */
            String str = message.toString();
            if (str.trim().equalsIgnoreCase("quit")) {
                session.closeNow();
                return;
            }
            Date date = new Date();
            session.write(date.toString());
            System.out.println("Message written...");
        }
        @Override
        public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
            /**
             * 当Session处于IDLE状态的时候,输出空闲状态次数;
             */
            System.out.println("IDLE:" + session.getIdleCount(status));
        }
    }
    
}

运行代码,在cmd(命令提示符) 中输入"telnet 127.0.0.1 9123",连接成功后随意输入字符,并按下回车,即可看到当前时间。

  1. 客户端

/**
 * mina客户端
 * @author mazaiting
 */
public class MinaClient {

    /**
     * 监听的端口
     */
    private static final int PORT = 9123;
    
    public static void start() {
        IoConnector connector = new NioSocketConnector();
        connector.setConnectTimeoutMillis(30000);
        connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(
                new TextLineCodecFactory(Charset.forName("UTF-8"), 
                LineDelimiter.WINDOWS.getValue(),
                LineDelimiter.WINDOWS.getValue())));
        connector.setHandler(new ClientHandler("你好!\r\n 大家好!"));
        connector.connect(new InetSocketAddress("localhost", 9123));        
    }
    
    public static void main(String[] args) {
        start();
    }
    
    
    private static class ClientHandler extends IoHandlerAdapter{
        private String values;
        public ClientHandler(String values) {
            this.values = values;
        }
        @Override
        public void sessionOpened(IoSession session) throws Exception {
            session.write(values);
        }
        @Override
        public void messageReceived(IoSession session, Object message) throws Exception {
            System.out.println(message.toString());
        }
    }
}

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
java作业调度框架Quartz
在软件开发中,很多时候需要在特定时间的时间执行某些操作,比如每天的凌晨三点、每周的周日、每个月的15号,Apache Quartz就是一个开源的作业调度框架,可以让计划的程序任务一个预定义的日期和时间运行。
843 0
java-框架-Quartz
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的日程序表。
1037 0
在Xuper链上部署Java语言智能合约和分析存证合约的实现逻辑(2)
在Xuper链上部署Java语言智能合约和分析存证合约的实现逻辑(2)
82 0
java 利用 LinkedList类实现 数据结构 栈.......
  /* java.util.LinkedList 类实现栈操作 栈是个后进先出的线性表 */ import java.util.*; class  Test {   private LinkedList ll=new LinkedList();   //创建栈        void push(Object o)    {        ll.
643 0
java LinkedList类实现 队列
  /* LinkedList 类实现队列 队列 是FIFO  先进先出 FIRST  IN  FIRST OUT      一边进去 另一边出来 LinkedList 底层是采用链表完成 ArrayList底层采用数组完成 对数据的查找操作 用数组更快 */ import java.
614 0
java HashSet类实现哈希表
 /*HashSet 类实现哈希表(散列表) 我们应该为插入到 哈希表的各个对象重写 hashCode()和equals() 方法  String 类重写的   hashCode() 是根据字符串计算的   Object 类的       hashCode() 是根据内存地址计算散列地址 哈希表只能通过迭代器迭代元素 Iterator */ import java.
600 0
java 中的多线程 内部类实现 数据共享 和 Runnable实现数据共享
  /* java 中Runnable的好处    可以实现共享一个数据     在一个类已经从其他类派生的时候 我们不能使用 直接从Thread类派生  那么这时候我们可以通过实现Runnable 接口来实现    class Test  {     public  s...
684 0
java多线程实现火车售票系统 以及java中的同步的实现 同步块 和同步方法同时 同步
  /* 利用Java 多线程模拟火车站售票系统  了解java中的同步 class  Test {  public  static void main(String []args)  {      SellThread st=new SellThread(); //创建一个实现了implements接口的对象     new Thread(st).
817 0
Java实现对MongoDB的AND、OR和IN操作
       在MongoDB的官方文档中关于Java操作的介绍,只给出了很简单的几个例子。这些例子虽然可以满足一定的需求,但是还并不是太完全。下面是我根据网页中的提示写的几个例子。        1.背景。
750 0
* java 中的数组 对象数组 以及main方法中的参数 x y不用中间参数实现交换
 /*  java 中的数组  对象数组   以及main方法中的参数    x y不用中间参数实现交换java 基本数据类型 的数组 初始化元素为 0java中数组名.length表示数组中元素的个数 main方法中的 args[] 从0开始 是java 类  后面的字符串  args.
683 0
+关注
凌浩雨
毕业于贵州大学大数据与信息工程学院,目前是一名移动端工程师,就职于北京乾元大通信息技术有限责任公司。
397
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载