Mina入门demo
初识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的更多相关文章
- JAVA通信系列二:mina入门总结
一.学习资料 Mina入门实例(一) http://www.cnblogs.com/juepei/p/3939119.html Mina入门教程(二)----Spring4 集成Mina http:/ ...
- Mina入门:mina版之HelloWorld
一,前言: 在完成上篇文章<Mina入门:Java NIO框架Mina.Netty.Grizzly简介与对比>之后,我们现在可以正式切入Mina入门学习了. 二,搭建项目结构与解决项目依赖 ...
- Apache Mina入门实例
一.mina是啥 ApacheMINA是一个网络应用程序框架,用来帮助用户简单地开发高性能和高可扩展性的网络应用程序.它提供了一个通过Java NIO在不同的传输例如TCP/IP和UDP/IP上抽象的 ...
- 【SSH系列】初识spring+入门demo
学习过了hibernate,也就是冬天,经过一个冬天的冬眠,当春风吹绿大地,万物复苏,我们迎来了spring,在前面的一系列博文中,小编介绍hibernate的相关知识,接下来的博文中,小编将继续介绍 ...
- 基于springboot构建dubbo的入门demo
之前记录了构建dubbo入门demo所需的环境以及基于普通maven项目构建dubbo的入门案例,今天记录在这些的基础上基于springboot来构建dubbo的入门demo:众所周知,springb ...
- apollo入门demo实战(二)
1. apollo入门demo实战(二) 1.1. 下载demo 从下列地址下载官方脚本和官方代码 https://github.com/nobodyiam/apollo-build-scripts ...
- lua入门demo(HelloWorld+redis读取)
1. lua入门demo 1.1. 入门之Hello World!! 由于我习惯用docker安装各种软件,这次的lua脚本也是运行在docker容器上 openresty是nginx+lua的各种模 ...
- netty入门demo(一)
目录 前言 正文 代码部分 服务端 客服端 测试结果一: 解决粘包,拆包的问题 总结 前言 最近做一个项目: 大概需求: 多个温度传感器不断向java服务发送温度数据,该传感器采用socket发送数据 ...
- canal入门Demo
关于canal具体的原理,以及应用场景,可以参考开发文档:https://github.com/alibaba/canal 下面给出canal的入门Demo (一)部署canal服务器 可以参考官方文 ...
随机推荐
- Xcode弱网测试工具
Network Link Conditioner Network Link Conditioner工具是Mac下提供的一个弱网测试工具. 安装Network Link Conditioner Xcod ...
- txt文本怎么去除重复项
txt文本怎么去除重复项?做网络推广的朋友经常会遇到这样的问题,txt文本文件里面有许多人名或者电话号码用来发送邮件或者短信,通常有许多是重复的,下面我来介绍两个方法来去除重复项,以人名为范本讲解. ...
- Canvas保存为图片
public static void GenerateCanvas(string imgSaveName, int canvasWidth, int canvasHeight, string imgD ...
- 使用Filter对POST和GET方式的请求参数的进行统一解码
一.过滤器 二.自定义request类
- 基于zookeeper实现高性能分布式锁
实现原理:利用zookeeper的持久性节点和Watcher机制 具体步骤: 1.创建持久性节点 zkLock 2.在此父节点下创建子节点列表,name按顺序定义 3.Java程序获取该节点下的所有顺 ...
- T-SQL查询进阶--SQL Server中的事务与锁
为什么需要锁 在任何多用户的数据库中,必须有一套用于数据修改的一致的规则,当两个不同的进程试图同时修改同一份数据时,数据库管理系统(DBMS)负责解决它们之间潜在的冲突.任何关系数据库必须支持事务的A ...
- Vue生命周期函数
生命周期函数: 组件挂载,以及组件更新,组建销毁的时候出发的一系列方法. beforeCreate:实例创建之前 created:实例创建完成 beforeMount:模板编译之前 mounted:模 ...
- Android学习笔记 Toast屏幕提示组件的使用方法
activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&qu ...
- HTML4.0 需要掌握的主要内容
常用标签: <html></html> 创建一个HTML文档 <head></head> 设置文档标题和其它在网页中不显示的信息 <title&g ...
- 十二、Nodejs 包与 NPM 第三方模块安装 package.json 以及 CNPM
1. 包 Nodejs 中除了它自己提供的核心模块外,我们可以自定义模块,也可以使用第三方的模块.Nodejs 中第三方模块由包组成,可以通过包来对一组具有相互依赖关系的模块进行统一管理. 在 Nod ...