Mina框架的使用[通俗易懂]

什么是Mina框架ApacheMina是一个能够帮助用户开发高性能和高伸缩性网络应用程序的框架。它通过Javanio技术基于TCP/IP和UDP/IP协议提供了抽象的、事件驱动的、异步的API。是用来代替NIO网络框架的,对NIO框架进行了一层封装的Socket库。Mina主页下载地址为什么使用Mina?传统socket:阻塞式通信每建立一个Socket连接时,同时创建一个新线程对该Soc

大家好,又见面了,我是你们的朋友全栈君。

什么是Mina框架

Apache Mina是一个能够帮助用户开发高性能和高伸缩性网络应用程序的框架。它通过Java nio技术基于TCP/IP和UDP/IP协议提供了抽象的、事件驱动的、异步的API。是用来代替
NIO网络框架的,对NIO框架进行了一层封装的Socket库。

Mina主页
下载地址

为什么使用Mina?

传统socket:阻塞式通信

每建立一个Socket连接时,同时创建一个新线程对该Socket进行单独通信(采用阻塞的方式通信)。这种方式具有很高的响应速度,并且控制起来也很简单,在连接数较少的时候非常有效,但是如果对每一个连接都产生一个线程的无疑是对系统资源的一种浪费,如果连接数较多将会出现资源不足的情况。

nio:非阻塞通信

nio设计背后的基石:反应器模式,用于事件多路分离和分派的体系结构模式。

反应器模式的核心功能如下:
将事件多路分用
将事件分派到各自相应的事件处理程序

NIO 的非阻塞 I/O 机制是围绕 选择器和 通道构建的。Channel 类表示服务器和客户机之间的一种通信机制。Selector 类是 Channel 的多路复用器。 Selector 类将传入客户机请求多路分用并将它们分派到各自的请求处理程序。

通道(Channel 类):表示服务器和客户机之间的一种通信机制。
选择器(Selector类):是 Channel 的多路复用器。

Selector 类将传入的客户机请求多路分用并将它们分派到各自的请求处理程序。

简单的来说:NIO是一个基于事件的IO架构。
最基本的思想就是:有事件我通知你,你再去做你的事情。而且NIO的主线程只有一个,不像传统的模型,需要多个线程以应对客户端请求,也减轻了JVM的工作量。

当Channel注册至Selector以后,经典的调用方法如下:nio中取得事件通知,就是在selector的select事件中完成的。在selector事件时有一个线程向操作系统询问,selector中注册的Channel&&SelectionKey的键值对的各种事件是否有发生,如果有则添加到selector的selectedKeys属性Set中去,并返回本次有多少个感兴趣的事情发生。如果发现这个值>0,表示有事件发生,马上迭代selectedKeys中的SelectionKey,根据Key中的表示的事件,来做相应的处理。实际上,这段说明表明了异步socket的核心,即异步socket不过是将多个socket的调度(或者还有他们的线程调度)全部交给操作系统自己去完成,异步的核心Selector,不过是将这些调度收集、分发而已。

传统的socket实现C/S通讯
服务端

public class SocketServer {
    public static void main(String[] args) {
        SocketServer ss = new SocketServer();
        ss.startServer();
    }

    public void startServer() {
        ServerSocket serverSocket;
        Socket socket;
        BufferedReader reader;
        BufferedWriter writer;
        try {
            // new一个socket对象并且设置端口号
            serverSocket = new ServerSocket(9898);
            System.out.println("服务器打开了");
            socket = serverSocket.accept();
            System.out.println("client" + socket.hashCode() + "connect");
            reader = new BufferedReader(new InputStreamReader(
                    socket.getInputStream()));
            writer = new BufferedWriter(new OutputStreamWriter(
                    socket.getOutputStream()));
            String recevierMsg;
            while ((recevierMsg = reader.readLine()) != null) {
                System.out.println(recevierMsg + "11");
                writer.write(recevierMsg+"response");
            }

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

流我没有关,代码很繁琐而且当多个客户端连入也没有处理 那让我们看看使用mina建的客户端
先导入这两个包

public class MinaSocket {
    public static void main(String[] args) {
        try {
            NioSocketAcceptor acceptor = new NioSocketAcceptor();
            acceptor.setHandler(new MyserverHandler());
            acceptor.getFilterChain().addLast("code", new ProtocolCodecFilter(new TextLineCodecFactory()));// 过滤
            acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 5000);
            acceptor.bind(new InetSocketAddress(8989));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}

仅需要4不即可完成
在MyserverHandler写消息处理的代码

import java.awt.datatransfer.StringSelection;

import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;

/** * 专门用来处理消息收发的类 * * @author Jay-Tang * */
public class MyserverHandler extends IoHandlerAdapter { 
   

    @Override
    public void exceptionCaught(IoSession session, Throwable cause)
            throws Exception {
        // TODO Auto-generated method stub
        super.exceptionCaught(session, cause);
        System.out.println("exceptionCaught");
    }
//收到消息
    @Override
    public void messageReceived(IoSession session, Object message)
            throws Exception {
        // TODO Auto-generated method stub
        super.messageReceived(session, message);
        String s = (String) message;
        System.out.println(s);
        session.write("server reply"+s);
    }

    @Override
    public void messageSent(IoSession session, Object message) throws Exception {
        // TODO Auto-generated method stub
        super.messageSent(session, message);

        System.out.println("messageSent");

    }

    @Override
    public void sessionClosed(IoSession session) throws Exception {
        // TODO Auto-generated method stub
        super.sessionClosed(session);
        System.out.println("sessionClosed");
    }

    @Override
    public void sessionCreated(IoSession session) throws Exception {
        // TODO Auto-generated method stub
        super.sessionCreated(session);
        System.out.println("sessionCreated");
    }

    @Override
    public void sessionIdle(IoSession session, IdleStatus status)
            throws Exception {
        // TODO Auto-generated method stub
        super.sessionIdle(session, status);
        System.out.println("sessionIdle");
    }

    @Override
    public void sessionOpened(IoSession session) throws Exception {
        // TODO Auto-generated method stub
        super.sessionOpened(session);
        System.out.println("sessionOpened");
    }

}

从每个方法的名称就可以看出其要实现的功能
传统的Socket客户端代码

public class SocketClient {
    public static void main(String[] args) {
        SocketClient client = new SocketClient();
        client.start();
    }

    public void start() {
        BufferedReader inputReader = null;
        BufferedReader reader = null;
        BufferedWriter writer = null;
        Socket socket = null;
        try {
            socket = new Socket("127.0.0.1", 8989);
            reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            inputReader = new BufferedReader(new InputStreamReader(System.in));
            startServerReplyListener(reader);
            String inputContent;
            int count = 0;
            while (!(inputContent = inputReader.readLine()).equals("bye")) {
                writer.write(inputContent);
                if (count % 2 ==0) {
                    writer.write("\n");
                }
                count++;
                writer.flush();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                reader.close();
                writer.close();
                inputReader.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void startServerReplyListener(final BufferedReader reader) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    String response;
                    while ((response = reader.readLine()) != null) {
                        System.out.println(response);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

}

再来看看mina写的客户端


//客户端使用mina
public class MinaClient {
public static void main(String[] args) throws Exception{
NioSocketConnector connector=new    NioSocketConnector();
connector.setHandler(new MyclientrHandler());
connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new  TextLineCodecFactory()));
ConnectFuture futrue=connector.connect(new InetSocketAddress("127.0.0.1",8989));
futrue.awaitUninterruptibly();
IoSession ioSession=futrue.getSession();
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String inputContent;
while(!(inputContent=reader.readLine()).equals("bye")){
    ioSession.write(inputContent);


}
}
}

也只需要四部 ,再写一个MyclientrHandler实现功能
代码与服务端的handler相似

//客户端使用mina
public class MinaClient {
public static void main(String[] args) throws Exception{
NioSocketConnector connector=new    NioSocketConnector();
connector.setHandler(new MyclientrHandler());
connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new  TextLineCodecFactory()));
ConnectFuture futrue=connector.connect(new InetSocketAddress("127.0.0.1",8989));
futrue.awaitUninterruptibly();
IoSession ioSession=futrue.getSession();
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String inputContent;
while(!(inputContent=reader.readLine()).equals("bye")){
    ioSession.write(inputContent);


}
}
}

这是简单使用mina建立客户端和服务端的操作
都是使用TextLineCodecFactory()实现解码,其实还可以自己一个工厂类MyTextLineCodecFactory来继承ProtocolCodecFactory ~ 这里就不提到了。。。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/126543.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 犀利!分清候选码和主码

    犀利!分清候选码和主码

  • 一位10年程序员生涯的总结与经验忠告分享

    一位10年程序员生涯的总结与经验忠告分享

    2021年10月10日
  • css3颜色渐变_灰色渐变图片

    css3颜色渐变_灰色渐变图片Document*{margin:0;padding:0}.words{font-size:25px;font-weight:700;text-align:center;margin:20px0}div{width:300px;height:150px;margin:0auto10px;border:1pxsolid#ddd;}.box1{background:-webkit-linea…

    2022年10月26日
  • Mysql横向分组统计

    Mysql横向分组统计

  • Stm32看门狗(开始于2021-07-19)「建议收藏」

    Stm32看门狗(开始于2021-07-19)「建议收藏」Stm32看门狗????1.概述:独立看门狗:喂狗时间必须在0之前,否则计数器下降到0后,产生复位信号;窗口看门狗:喂狗时间必须在CFR寄存器(我们设置的窗口上限),和0x3F(窗口下限)之间(即在CR寄存器的第7位b6*(T6)*减小到零之前),否则(上限之前,或以达下限)均会产生复位信号。喂狗:即重新设置递减计数器CNT的值,也就是手册时序图中的”更新”(CNT).上窗口比较触发:当我们喂狗时,比较器会将当前(未写入时的)CNT的值与CFR低7位的值进行比较,查看是否超前喂狗.2.独立

  • git提交中E325: ATTENTION或E325: 注意 的解决方法

    git提交中E325: ATTENTION或E325: 注意 的解决方法问题引入首先看下图,在git提交、编辑、合并等过程中,如果没有将指令进行完就将git窗口关闭有时会出现这样的界面。原因分析git在指令意外中断时,一般会有一个缓存的机制,它会记住上次中断的问题。在下次进入vim指令时,如果很重要的中断一般会提示你前面有某个操作不当或者没有结束,就出现了上面的窗口。如果不解决就会一直缠着你,以至于出现该窗口后再输入git指令的话一般就不显示在…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号