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服务器 可以参考官方文 ...
随机推荐
- The Three Models of ASP.NET MVC Apps
12 June 2012 by Dino Esposito by Dino Esposito We've inherited from the original MVC pattern a ra ...
- HTML5拓扑3D机房,电力工控Web SCADA
http://www.hightopo.com/cn-index.html 一套丰富的JavaScript界面类库, 提供完整的基于HTML5图形界面组件库.使用HT for Web您可以轻松构建现代 ...
- 关于IIS配置SimpleHandlerFactory-Integrated在其模块列表中有一个错误模块ManagedPipelineHandler的错误处理
解决方法: 使用管理员运行aspnet_regiis.exe 命令:%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -i v ...
- React + Python 七月小说网 启程(一)
一.为啥要做这个网站 很久没有写技术相关的博客了,最近几个月忙飞,各种工作,技术根本学不完,很难受. 趁着春节期间,终于有空闲时间做自己爱做的事情了,美滋滋. 热爱技术,热爱小说,于是诞生了个这么玩意 ...
- C# 判断一个数是不是奇数/偶数
一般普通版: private bool IsOdd(int num) { ) == ; } 通过判断取余 现在升级版: private bool IsOdd(int num) { ) == ; } 通 ...
- JavaScript 如何工作:渲染引擎和性能优化技巧
翻译自:How JavaScript works: the rendering engine and tips to optimize its performance 这是探索 JavaScript ...
- ecliplse启动慢的优化方法(亲测有效)
本人使用的ecliplse IDE 版本是: Version: Photon Release (4.8.0)Build id: 20180619-1200 我的电脑配置是 Ecliplse启动差不多一 ...
- Spring容器管理对象和new对象
问题:一个业务类交给spring管理,并自动注入了其他业务类作为属性,方法中通过全局属性调用其他业务类的方法.当该业务类是通过new获取的情况下,该实例的属性会是null(不存在依赖注入实例),调用方 ...
- List_Delete
/*Sorting from little to large use List*/ #include <stdio.h> /* printf, scanf, NULL */ #includ ...
- MyBatis介绍及使用
一.介绍: 1.MyBatis实际上是Ibatis3.0版本以后的持久化层框架[也就是和数据库打交道的框架]! 2.和数据库打交道的技术有: 原生的JDBC技术--->Spring的JdbcTe ...