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 ~ 这里就不提到了。。。

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 煤矿人员定位系统(福利院上班怎么样)

    每个孩子都是祖国的花朵,他们的健康成长是我们的责任.尤其是福利院的孩子,他们被遗弃,孩子的心理已经造成了创伤,此时,孩子们的心理及身体的健康,我们必须实时监控.这样我们就可以对孩子们进行实时监控,随时随地的了解孩子们的生命体征的各项数据.例如,孩子的血压,心跳等等.甚至还可以使用尿湿监测系统.对孩子的生理问题进行监测.福利院人员定位技术背景:福利院人员定位办理体系,将射频识别技术应用于孩子定位办理,别离于每个房间门口和每个楼层的出口以及每栋楼门口和公寓门口…

    2022年4月16日
    51
  • Kubernetes Pod Evicted[通俗易懂]

    Kubernetes Pod Evicted[通俗易懂]一、背景以及措施近日Kubernetes测试集群Pod状态出现Evicted现象,但是项目还是能正常提供服务,最先的解决办法是手动将Evicted状态的Pod删除。#查看Evicted状态的Pod[ops@dev-gate~]#kubectlgetpods-nstaging-services|grepEvictedeureka-server-02-7f658c4dfc-zwtqk0/1Evicted

    2022年5月17日
    73
  • java mediatype属性_Java 如何获得文件的 Media Type「建议收藏」

    java mediatype属性_Java 如何获得文件的 Media Type「建议收藏」一般来说你可以使用ApacheTika来获得文件的类型。Tika是一个内容分析工具Maven设置maven的版本到你的POM文件中。org.apache.tikatika-core1.25测试代码例如,我们可以使用下面的测试代码。@TestpublicvoidwhenUsingTika_thenSuccess(){Filefile=newFile(“product.pn…

    2022年5月26日
    207
  • OpenGrok介绍「建议收藏」

    OpenGrok介绍「建议收藏」2019独角兽企业重金招聘Python工程师标准>>>…

    2022年5月4日
    37
  • 爱,该放弃吗_有一种爱叫做放手

    爱,该放弃吗_有一种爱叫做放手爱,绝不是缺了就找,更不是累了就换。   找一个能一起吃苦的,而不是一起享受的   找一个能一起承担的,而不是一起逃避的   找一个能对你负责的,而不是对爱情负责的   爱情是盲目的,生活是现实的   因为爱情只不过是人类为了逃避现实而衍生的产品   为了逃避现实,我寻找爱情   为了寻找爱情,我失去真情   失去了真情,才发现早已身陷虚情.   你以为爱情是什么?   一点点的动心,一点点的冲动

    2026年2月3日
    5
  • 【云原生 • Docker】镜像的迁移与备份、Dockerflie 使用方法

    【云原生 • Docker】镜像的迁移与备份、Dockerflie 使用方法Docker中镜像的迁移与备份,Dockerfile的使用方法(附案例)

    2022年9月22日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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