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服务器 可以参考官方文 ...
随机推荐
- Oracle数据库之单表查询
接着上一篇的分享,今天主要给大家分享的是关于数据中的单表查询,单表查询很基础,也很重要,但是任何一个初学者必须要掌握的姿势,单表查询就是对单个表进行操作,查询我们想要的数据.单表查询里面的内容也是比较 ...
- Capturing ASP.NET Application Startup Exceptions
It has become common practice to perform tasks during an ASP.NET applications start up process. Thes ...
- URAL 1204. Idempotents (扩展欧几里得)
题目链接 题意 : 给你一个同余方程, x*x ≡ x (mod n),让你求出所有的小于n的x. 思路 : 先来看同余的概念 :给定一个正整数m,如果两个整数a和b满足a-b能被m整除,即m|(a ...
- 如何将一个用utf-8编码的文本用java程序转换成ANSI编码的文本
jdk有一个关于UTF-8的bug所以加了一句 br.skip(1); bugID: http://bugs.java.com/view_bug.do?bug_id=4508058 public st ...
- springMVC传对象参数
springController: [java] view plaincopy @Controller @RequestMapping("/user") public UserCo ...
- Sublime for MacOS 使用技巧
1.创建软链接,使用命令直接打开sublime编辑器 ln -s "/Applications/Sublime Text.app/Contents/SharedSupport/bin/sub ...
- 浅谈短视频APP的发展趋势
2014年6月20日,在AppAnnie最新发布5月应用指数中,美拍荣登“非游戏类iOS榜单”全球下载量第一位置,成为全球iOS应用商店最热门APP.能在<AppAnnie应用指数>这份A ...
- C# 给图片添加透明的文字、图片水印
#region 添加水印 /// <summary> /// 添加文字水印 /// </summary> /// <param name="image" ...
- angular resolve路由
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from "@angular/router&q ...
- cinder侧卸载卷流程分析
cinder侧卸载卷分析,存储类型以lvm+iscsi的方式为分析基础在虚机卸载卷的过程中,主要涉及如下三个函数1)cinder.volume.api.begin_detaching 把volume的 ...