apache mina 自学

来源:互联网 发布:windows xp开机蓝屏 编辑:程序博客网 时间:2024/06/17 18:48
  • Mina 简介介绍以及通信流程

    mina 是Apche开发的一个开源的网络通信框架,.目前常用版本是Mina2.0.以及以上版本。它屏蔽了网络通信的细节,对socket 进行了封装,并且是nio的实现架构,可以快速开发网络通信。
    Ioservice接口 用于描述客户端服务端。用于描述我们的客户端和服务端接口,其子类是connector和Accptor,分别用于描述我们的客户端和服务端.IOproceser多线程环境来处理我们的连接请求流程.IoFilter提供数据的过滤工作:包括编解码,日志等信息的过滤.
    Hanlder就是我们的业务对象,自定义的handler需要实现IOHandlderAcceptor。
    这里写图片描述
    1)IOconnector->IOProcessor->IOFilter->Handler
    2)IOAccptor ->IOProcessor->IOFilter->Handler

  • 基础概念明确

长连接与短连接
1.长连接:
通信双发长期的保持一个连接状态不断开,比如腾讯qq,当登录qq的时候,我们就去连接我们腾讯服务器,一旦建立连接后,就不断开.除非发生异常,这样方式就是长连接,对于长连接比较耗费IO资源.
2.短连接:
通信双方不是保持一个长期的连接状态,比如http协议,当客户端发起http请求,服务器处理http请求,当服务器处理完成后,返回客服端数据后就断开链接,对于下次的连接请求需要重新发起.这种方式经常使用的方式.
阻塞与非阻塞
在阻塞模式下,在I/O操作完成前,执行的操作函数一直等候而不会立即返回,该函数所在的线程会阻塞在这里。相反,在非阻塞模式下,套接字函数会立即返回,而不管I/O是否完成,该函数所在的线程会继续运行。
NIO原理

通过selctor(选择器)管理所有的IO事件connction、accept客服端和服务端的读写.—–IO事件。当IO事件注册给我们的选择器的时候,选择器会给他们分配一个key(可以简单的理解成一个时间的标签)当IO事件完成过通过key值来找到相应的管道,然后通过管道发送数据和接收数据等操作.

  • 代码实现

以下创建了一个长连接的server端

public class MinaServer {    static int PORT=7088;    static IoAcceptor acceptor =null;    public static void main(String[] args) {        try{        acceptor = new NioSocketAcceptor();        //获得过滤器链        acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(                new TextLineCodecFactory(Charset.forName("UTF-8"),LineDelimiter.WINDOWS.getValue(),LineDelimiter.WINDOWS.getValue())));        //得到会话配置信息        acceptor.getSessionConfig().setReadBufferSize(1024);        acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);        acceptor.setHandler(new MyHanlder());        acceptor.bind(new InetSocketAddress(PORT));//绑定地址端口        System.out.println("服务器已经启动");        }catch(Exception e)        {        }    }

MyHanlder()

public class MyHanlder  extends IoHandlerAdapter{    @Override    public void exceptionCaught(IoSession session, Throwable cause) throws Exception {        System.out.println("出现异常");    }    @Override    public void inputClosed(IoSession session) throws Exception {        System.out.println("通信关闭");    }    @Override    public void messageReceived(IoSession session, Object message) throws Exception {        String meString = (String) message;        System.out.println("接收到"+meString);        Date date = new Date();        session.write("server to client  "+ date);    }    @Override    public void messageSent(IoSession session, Object message) throws Exception {System.out.println("消息发送");    }    @Override    public void sessionClosed(IoSession session) throws Exception {        System.out.println("会话关闭");    }    @Override    public void sessionCreated(IoSession session) throws Exception {        System.out.println("会话创建");    }    @Override    public void sessionIdle(IoSession session, IdleStatus status) throws Exception {        System.out.println("空闲");    }    @Override    public void sessionOpened(IoSession session) throws Exception {        System.out.println("会话打开");    }}

客户端

    static int port =7088;    static String host = "127.0.0.1";    public static void main(String[] args) {        IoSession ioSession=null;        IoConnector ioConnector = new NioSocketConnector();        ioConnector.setConnectTimeout(3000);//连接超时设置        //设置过滤器        ioConnector.getFilterChain().addLast("codec", new ProtocolCodecFilter(                new TextLineCodecFactory(Charset.forName("UTF-8"),LineDelimiter.WINDOWS.getValue(),LineDelimiter.WINDOWS.getValue())));        ioConnector.setHandler(new MyClientHandler());        //获得连接        ConnectFuture connectFuture = ioConnector.connect(new InetSocketAddress(host, port));//发起连接请求        connectFuture.awaitUninterruptibly(); //等待连接        ioSession=connectFuture.getSession();        ioSession.write("hello world");        ioSession.getCloseFuture().awaitUninterruptibly();//等待关闭连接        //关闭连接调用的方法        ioConnector.dispose();    }

MyClientHandler

public class MyClientHandler extends IoHandlerAdapter{    @Override    public void exceptionCaught(IoSession session, Throwable cause) throws Exception {        System.out.println("发生异常");    }    @Override    public void messageReceived(IoSession session, Object message) throws Exception {        String meString = (String) message;        System.out.println( "客户端收到的数据是"+ meString);    }}
  • 详细知识点

IOservice
管理网络通信的客户端和服务端,并且可以管理连接双方的会话,同样可以添加过滤器
常用方法 getFilterChain()获得过滤器,setHandler()设置业务响应事件,getSessionConfig 得到会话配置信息,dispose() 在关闭的时候所调用的方法。
IoConnector, IoAcceptor都是ioservice的子类
IoConnector connect 发起连接 setConnectTimeout 连接超时管理
IoAcceptor bind绑定监听端口 getLocalAddress()获得本地ip

IOFilter
对应用程序和网路的传输,也就是二进制和对象之间的转换
在应用层与业务层之间的过滤,可以自定义

IOSession
主要是描述网络通信双方所建立的连接之间的描述。完成对于连接的管理
可以发送读取数据,并且可以设置会话上下文信息
getAttribute()获得上下文属性 setAttribute()设置上下文
read()读取数据,write()写入数据
IOsessionconfig ()提供对连接配置信息的描述
设置读写缓冲区信息,读写之间的空闲时间,连接超时
setIdleTime()获得读写空闲时间方法

多线程环境:
1 通过NioSocketAcceptor(int processorCount) 构造函数可以指定多线程的个数.
2 通过NioSocketConnector(int processorCount) 构造函数也可以指定多线程的个数.

0 0
原创粉丝点击