初识Mina,简要记录理解内容和实现demo。

这里先简述一下BIO和NIO的区别:

同步阻塞IO(BIO):一个连接一个线程,客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,可以通过线程池机制改善。 
同步非阻塞IO(NIO):一个请求一个线程,客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。 
异步阻塞IO(AIO):一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。

Mina定义:

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

Mina好处:

NIO基于事件驱动思想,主要解决BIO的高并发问题(当多客户端请求服务器时每一个连接都需要启动一个线程来单独进行处理,而内存是有限的,当客户端数大到一定程度时候即便是使用线程池也无法解决内存有限和OS自身对线程数的限制带来的问题),但是NIO的复杂让很多开发人员感到痛苦,所以诞生了Mina框架,让我们可以不必考虑如何实现NIO方案,直接使用Mina即可快速进行网络编程。(注:Mina还支持多协议通信)

Mina的接口:

IoService:mina请求接受器(IoAcceptor)以及连接器(IoConnector)的一个抽象的父类,作用就是提供连接和接受请求的服务(封装了IO操作,不需要自己实现异步和线程,直接使用就可以了)。

IoProcessor:请求处理器,拥有自己的Selector,负责请求的处理工作,包括监听事件的更改,filterChain的建立,响应事件的调用(sessionCreated、sessionOpened、messageRecieved等)以及IO读写操作。

IoFilter:过滤器,不多解释,数据的encode 与decode是我们最需要关注的。

IoHandler:负责编写业务逻辑,也就是接收、发送数据的接口,开发者自己实现该接口,做逻辑处理。

工作流程:

(1)创建IoService

(2)添加过滤器/拦截器IoFilterChain

(3)实现IoHandler对数据进行业务逻辑处理

不啰嗦直接上代码,代码中会有注释:

服务端:

/**
* @author huangzhang
* @description
* @date Created in 2018/7/17 11:46
*/
public class MyServer {
public static void main(String[] args) throws Exception{
// 新建acceptor:服务端
IoAcceptor ioAcceptor = new NioSocketAcceptor();
//设置读取数据缓冲区大小
ioAcceptor.getSessionConfig().setReadBufferSize(2048);
//指定了什么时候检查空闲 session
ioAcceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE,10);
//设定消息编码规则拦截器
ioAcceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory()));
//设置Handler
ioAcceptor.setHandler(new ServerHandler());
ioAcceptor.bind(new InetSocketAddress(8080));
}
}

服务端handler:

/**
* @author huangzhang
* @description
* @date Created in 2018/7/17 11:52
*/
public class ServerHandler extends IoHandlerAdapter {
private final Logger logger = LoggerFactory.getLogger(ServerHandler.class); @Override
public void sessionCreated(IoSession session) throws Exception {
System.out.println(" Server session created");
} @Override
public void sessionOpened(IoSession session) throws Exception {
System.out.println(" Server connection succeed");
} @Override
public void sessionClosed(IoSession session) throws Exception {
System.out.println(" Server session closed");
} @Override
public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
System.out.println(" Server session idle");
} @Override
public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
System.out.println(" Server caught:"+cause);
} @Override
public void messageReceived(IoSession session, Object message) throws Exception {
String str = message.toString();
logger.info("The message received is [ "+ str +"]");
if (str.endsWith("quit")){
session.close(true);
return;
}
session.write("啦啦啦" + message);
}
}

客户端:

/**
* @author huangzhang
* @description
* @date Created in 2018/7/17 12:08
*/
public class ClientHandler extends IoHandlerAdapter { @Override
public void sessionOpened(IoSession session) throws Exception {
System.out.println("Client connection succeed");
} @Override
public void sessionClosed(IoSession session) throws Exception {
System.out.println("Client connection closed");
} @Override
public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
System.out.println("Client connection idle");
} @Override
public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
System.out.println("Client caught:"+ cause);
} @Override
public void messageReceived(IoSession session, Object message) throws Exception {
System.out.println("Client received :"+ message.toString());
} @Override
public void messageSent(IoSession session, Object message) throws Exception {
System.out.println("Client send:"+ message);
}
}

客户端handler:

/**
* @author huangzhang
* @description
* @date Created in 2018/7/17 12:04
*/
public class MyClient {
public static void main(String[] args) {
//建立一个connector
IoConnector ioConnector = new NioSocketConnector();
//设置连接超时时间
ioConnector.setConnectTimeoutMillis(2000);
//设置编码过滤器
ioConnector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory()));
//设置消息处理handler
ioConnector.setHandler(new ClientHandler());
//连接服务器
ConnectFuture future = ioConnector.connect(new InetSocketAddress("localhost",8080));
//阻塞直至连接成功
future.awaitUninterruptibly();
//client从控制台输入内容
BufferedReader bufferedReader = null;
try{
bufferedReader = new BufferedReader(new InputStreamReader(System.in,"UTF-8"));
String string;
while (!(string = bufferedReader.readLine()).equals("exit")){
future.getSession().write("客户端发送消息:"+ string);
}
}catch (IOException e){
e.printStackTrace();
}
}
}

先运行服务端,启动服务,然后运行客户端,与服务端建立连接,然后通信(客户端发送消息是从控制台输入的)。

Mina入门demo的更多相关文章

  1. JAVA通信系列二:mina入门总结

    一.学习资料 Mina入门实例(一) http://www.cnblogs.com/juepei/p/3939119.html Mina入门教程(二)----Spring4 集成Mina http:/ ...

  2. Mina入门:mina版之HelloWorld

    一,前言: 在完成上篇文章<Mina入门:Java NIO框架Mina.Netty.Grizzly简介与对比>之后,我们现在可以正式切入Mina入门学习了. 二,搭建项目结构与解决项目依赖 ...

  3. Apache Mina入门实例

    一.mina是啥 ApacheMINA是一个网络应用程序框架,用来帮助用户简单地开发高性能和高可扩展性的网络应用程序.它提供了一个通过Java NIO在不同的传输例如TCP/IP和UDP/IP上抽象的 ...

  4. 【SSH系列】初识spring+入门demo

    学习过了hibernate,也就是冬天,经过一个冬天的冬眠,当春风吹绿大地,万物复苏,我们迎来了spring,在前面的一系列博文中,小编介绍hibernate的相关知识,接下来的博文中,小编将继续介绍 ...

  5. 基于springboot构建dubbo的入门demo

    之前记录了构建dubbo入门demo所需的环境以及基于普通maven项目构建dubbo的入门案例,今天记录在这些的基础上基于springboot来构建dubbo的入门demo:众所周知,springb ...

  6. apollo入门demo实战(二)

    1. apollo入门demo实战(二) 1.1. 下载demo 从下列地址下载官方脚本和官方代码 https://github.com/nobodyiam/apollo-build-scripts ...

  7. lua入门demo(HelloWorld+redis读取)

    1. lua入门demo 1.1. 入门之Hello World!! 由于我习惯用docker安装各种软件,这次的lua脚本也是运行在docker容器上 openresty是nginx+lua的各种模 ...

  8. netty入门demo(一)

    目录 前言 正文 代码部分 服务端 客服端 测试结果一: 解决粘包,拆包的问题 总结 前言 最近做一个项目: 大概需求: 多个温度传感器不断向java服务发送温度数据,该传感器采用socket发送数据 ...

  9. canal入门Demo

    关于canal具体的原理,以及应用场景,可以参考开发文档:https://github.com/alibaba/canal 下面给出canal的入门Demo (一)部署canal服务器 可以参考官方文 ...

随机推荐

  1. Head First Python之2函数模块

    模块就是一个包含Python代码的文本文件,以.py结尾. 第三方模块都在PyPI(python package index)上,可使用PyPI发布你的模块,供他人使用. 注释代码 # coding= ...

  2. git手动解决内容冲突

    <span style="font-size:18px;">git checkout -b lab4 origin/lab4 git merge lab3</sp ...

  3. Js 正则获取Html元素

    var html = $("#summaryTemplate").html(); var imageMath = /<img [^<,>]*(?=target-t ...

  4. 【连载】redis库存操作,分布式锁的四种实现方式[四]--基于Redis lua脚本机制实现分布式锁

    一.redis lua介绍 Redis 提供了非常丰富的指令集,但是用户依然不满足,希望可以自定义扩充若干指令来完成一些特定领域的问题.Redis 为这样的用户场景提供了 lua 脚本支持,用户可以向 ...

  5. c++类 初始化另一对象

    Cbox类中对象a  可以直接赋值给对象b,无论类中数据成员是私有还是共有.且在创建a时调用了一次构造函数,b调用的是另外的默认构造函数: #include<iostream> using ...

  6. docker系列 参考文章

    Docker 系列一(概念原理和安装) Docker 系列二(操作镜像) Docker 系列三(容器管理) 持续更新... ubuntu 安装docker 参考文章 :(https://blog.cs ...

  7. 洛谷P4495 [HAOI2018]奇怪的背包(数论)

    题面 传送门 题解 好神仙的思路啊--orzyyb 因为不限次数,所以一个体积为\(V_i\)的物品可以表示出所有重量为\(\gcd(V_i,P)\)的倍数的物品,而所有物品的总和就是这些所有的\(\ ...

  8. HDU6300-2018ACM暑假多校联合训练1003-Triangle Partition

    题意是给3n个点,其中不可能存在任意三点共线的情况,让你在其中建n个三角形,点不能重复使用,三角形不能相互覆盖 做法是给每个点排序,按照先y轴排,再x轴排的顺序,三个三个一组从下往上输出,有人说是凸包 ...

  9. 整理LVS架构压力测试工作

    首先,测试环境在模拟环境下进行.     测试环境:1director(apache2.2) + 1realserver(jboss4.2.3GA)+1databaseserver(oracle9i) ...

  10. java集合类学习笔记之LinkList

    1.简述 LinkList的底层其实就是一个双向链表,所谓的链表就是一个LinkList内部静态静态类(Node),对LinkList的所有操作本质上就是通过对LinkList中新建的Node对象 进 ...