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)


相关推荐

  • 【python二级-练习题】

    【python二级-练习题】2、随机密码验证题目描述:代码如下:3、信息分配表(字典)题目描述:代码如下:4、全模式分词(jieba)题目描述:代码如下:5、数字金字塔题目描述:6、求最大值、最小值及平均值题目描述:代码如下:7、交换变量题目描述:代码如下:或或8、输入密码-三次机会题目描述:代码如下:9、水仙花数题目描述:代码如下:或或或10、增加与去掉题目描述:代码如下:11、添加通讯录信息题目

    2022年10月12日
  • 关于异步FIFO的知识点–详细代码解释(很干)[通俗易懂]

    关于异步FIFO的知识点–详细代码解释(很干)[通俗易懂]异步FIFO的读写控制详解

  • linux环境变量的配置_centos环境变量配置文件

    linux环境变量的配置_centos环境变量配置文件前言在自定义安装软件的时候,经常需要配置环境变量,下面进行详细解析 环境变量配置文件|用户|配置文件||:|:||系统环境|/ect/profil

  • 基于STM32的嵌入式语音识别模块设计实现「建议收藏」

    基于STM32的嵌入式语音识别模块设计实现「建议收藏」介绍了一种以ARM为核心的嵌入式语音识别模块的设计与实现。模块的核心处理单元选用ST公司的基于ARMCortex-M3内核的32位处理器STM32F103C8T6。本模块以对话管理单元为中心,通过以LD3320芯片为核心的硬件单元实现语音识别功能,采用嵌入式操作系统μC/OS-II来实现统一的任务调度和外围设备管理。经过大量的实验数据验证,本文设计的语音识别模块具有高实时性、高识别率、高稳定性的…

  • socket rst_socket通信编程

    socket rst_socket通信编程产生RST的三个条件:1.目的地为某端口的SYN到达,然而该端口上没有正在监听的服务器;2.TCP想取消一个已有的连接;3.TCP接收到一个根本不存在的连接上的分节; 现在模拟上面的三种情况:client:structsockaddr_inserverAdd;bzero(&serverAdd,sizeof(serverAdd));

  • 华为ensp模拟器安装教程_华为模拟器路由器无法启动

    华为ensp模拟器安装教程_华为模拟器路由器无法启动eNSP是个很好用的学习工具,但是其安装过程并不那么简单,很多同学在模拟器的安装过程遇到了诸多问题。安装的软件如下:1、V-BOX版本5.16,经实际测试完美兼容最新版eNSP在win-7和win-10的运转;2、Wireshark抓包软件,汉化版,在win-7,win-10与ENSP工作正常;3、eNSP最新版1.300.10,实际检验在win-7,win-10工作正常,自带镜像工作正…

发表回复

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

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