MINA网络通信框架

标签: 未分类 | 发表时间:2012-04-11 12:45 | 作者:kunshuo
出处:http://rdc.taobao.com/team/jm

基本介绍:

Apache MINA 2是一个开发高性能和高可伸缩性网络应用程序的网络应用框架。它提供了一个抽象的事件驱动的异步API,可以使用TCP/IP、UDP/IP、串口和虚拟机内部的管道等传输方式。Apache MINA 2可以作为开发网络应用程序的一个良好基础。


Mina 的API 将真正的网络通信与我们的应用程序隔离开来,你只需要关心你要发送、

接收的数据以及你的业务逻辑即可。


mina的基本架构:






在图中的模块链中,IoService 便是应用程序的入口,相当于我们前面代码中的 IoAccepter,IoAccepter 便是 IoService 的一个扩展接口。IoService 接口可以用来添加多个 IoFilter,这些 IoFilter 符合责任链模式并由 IoProcessor 线程负责调用。而 IoAccepter 在 ioService 接口的基础上还提供绑定某个通讯端口以及取消绑定的接口。ioHandler则为应用逻辑处理类。

主要类以及接口:

(1.)IoService:这个接口在一个线程上负责套接字的建立,拥有自己的Selector,监

听是否有连接被建立。

(2.)IoProcessor:这个接口在另一个线程上负责检查是否有数据在通道上读写,也就是

说它也拥有自己的Selector,这是与我们使用JAVA NIO编码时的一个不同之处,

通常在JAVA NIO编码中,我们都是使用一个Selector,也就是不区分IoService

与IoProcessor两个功能接口。另外,IoProcessor负责调用注册在IoService上

的过滤器,并在过滤器链之后调用IoHandler。

(3.)IoFilter:这个接口定义一组拦截器,这些拦截器可以包括日志输出、黑名单过滤、

数据的编码(write方向)与解码(read方向)等功能,其中数据的encode与decode

是最为重要的、也是你在使用Mina时最主要关注的地方。

(4.)IoHandler:这个接口负责编写业务逻辑,也就是接收、发送数据的地方。

(5.)IoSession:Session可以理解为服务器与客户端的特定连接,该连接由服务器地址、端口以及客户端地址、端口来决定。客户端发起请求时,指定服务器地址和端口,客户端也会指定或者根据网络路由信息自动指定一个地址、自动分配一个端口。这个地址、端口对构成一个Session。Session是服务器端对这种连接的抽象,MINA对其进行了封装,定义了IoSession接口,用来代表客户端与服务器的连接,在服务器端来指代客户端,实现对客户端的操作、绑定与客户端有关的信息与对象。通过利用Session的这个概念,编写程序时就可以在服务器端非常方便地区分出是当前处理的是哪个客户端的请求、维持客户端的状态信息、可以实现客户端之间相互通讯。

一图胜千言,MINA的核心类图:



服务端代码大致如下:

Java代码
  1. //初始化Acceptor—可以不指定线程数量,MINA2里面默认是CPU数量+2    
  2. //是你的工作主线程     
  3. NioSocketAcceptor acceptor = new NioSocketAcceptor(5);  
  4. //建立线程池  
  5. java.util.concurrent.Executor threadPool = newFixedThreadPool(1500);  
  6. //加入过滤器(Filter)到Acceptor           
  7. acceptor.getFilterChain().addLast(“exector”, new ExecutorFilter(threadPool));  
  8. //编码解码器  
  9. acceptor.getFilterChain().addLast(“codec”,new ProtocolCodecFilter(new WebDecoder(),new XmlEncoder()));  
  10. //日志        
  11. LoggingFilter filter = new LoggingFilter();  
  12. filter.setExceptionCaughtLogLevel(LogLevel.DEBUG);  
  13. filter.setMessageReceivedLogLevel(LogLevel.DEBUG);  
  14. filter.setMessageSentLogLevel(LogLevel.DEBUG);  
  15. filter.setSessionClosedLogLevel(LogLevel.DEBUG);  
  16. filter.setSessionCreatedLogLevel(LogLevel.DEBUG);  
  17. filter.setSessionIdleLogLevel(LogLevel.DEBUG);  
  18. filter.setSessionOpenedLogLevel(LogLevel.DEBUG);  
  19. acceptor.getFilterChain().addLast(“logger”, filter);  
  20. //设置的是主服务监听的端口可以重用  
  21. acceptor.setReuseAddress(true);  
  22. //设置每一个非主监听连接的端口可以重用          
  23. acceptor.getSessionConfig().setReuseAddress(true);  
  24. //MINA2中,当启动一个服务端的时候,要设定初始化缓冲区的长度,如果不设置这个值,系统默认为2048,当客户端发过来的消息超过设定值的时候,  
  25. //MINA2的机制是分段接受的,将字符是放入缓冲区中读取,所以在读取消息的时候,需要判断有多少次。这样的好处就是可以节省通讯的流量。  
  26. //设置输入缓冲区的大小  
  27. acceptor.getSessionConfig().setReceiveBufferSize(1024);  
  28. //设置输出缓冲区的大小  
  29. acceptor.getSessionConfig().setSendBufferSize(10240);  
  30. //设置为非延迟发送,为true则不组装成大包发送,收到东西马上发出           
  31. acceptor.getSessionConfig().setTcpNoDelay(true);  
  32. //设置主服务监听端口的监听队列的最大值为100,如果当前已经有100个连接,再新的连接来将被服务器拒绝           
  33. acceptor.setBacklog(100);  
  34. acceptor.setDefaultLocalAddress(new InetSocketAddress(port));  
  35. //加入处理器(Handler)到Acceptor           
  36. acceptor.setHandler(new YourHandler());  
  37. acceptor.bind();  
        //初始化Acceptor—可以不指定线程数量,MINA2里面默认是CPU数量+2  
        //是你的工作主线程   
        NioSocketAcceptor acceptor = new NioSocketAcceptor(5);
        //建立线程池
        java.util.concurrent.Executor threadPool = newFixedThreadPool(1500);
        //加入过滤器(Filter)到Acceptor         
        acceptor.getFilterChain().addLast("exector", new ExecutorFilter(threadPool));
        //编码解码器
        acceptor.getFilterChain().addLast("codec",new ProtocolCodecFilter(new WebDecoder(),new XmlEncoder()));
        //日志      
        LoggingFilter filter = new LoggingFilter();
        filter.setExceptionCaughtLogLevel(LogLevel.DEBUG);
        filter.setMessageReceivedLogLevel(LogLevel.DEBUG);
        filter.setMessageSentLogLevel(LogLevel.DEBUG);
        filter.setSessionClosedLogLevel(LogLevel.DEBUG);
        filter.setSessionCreatedLogLevel(LogLevel.DEBUG);
        filter.setSessionIdleLogLevel(LogLevel.DEBUG);
        filter.setSessionOpenedLogLevel(LogLevel.DEBUG);
        acceptor.getFilterChain().addLast("logger", filter);
        //设置的是主服务监听的端口可以重用
        acceptor.setReuseAddress(true);
        //设置每一个非主监听连接的端口可以重用        
        acceptor.getSessionConfig().setReuseAddress(true);
        //MINA2中,当启动一个服务端的时候,要设定初始化缓冲区的长度,如果不设置这个值,系统默认为2048,当客户端发过来的消息超过设定值的时候,
        //MINA2的机制是分段接受的,将字符是放入缓冲区中读取,所以在读取消息的时候,需要判断有多少次。这样的好处就是可以节省通讯的流量。
        //设置输入缓冲区的大小
        acceptor.getSessionConfig().setReceiveBufferSize(1024);
        //设置输出缓冲区的大小
        acceptor.getSessionConfig().setSendBufferSize(10240);
        //设置为非延迟发送,为true则不组装成大包发送,收到东西马上发出         
        acceptor.getSessionConfig().setTcpNoDelay(true);
        //设置主服务监听端口的监听队列的最大值为100,如果当前已经有100个连接,再新的连接来将被服务器拒绝         
        acceptor.setBacklog(100);
        acceptor.setDefaultLocalAddress(new InetSocketAddress(port));
        //加入处理器(Handler)到Acceptor         
        acceptor.setHandler(new YourHandler());
        acceptor.bind();

客户端代码大致如下:

客户端的初始化和服务器端其实是一样的,就是初始化类不一样,客户端是作为发送者的。

Java代码
  1. SocketConnector connector = new NioSocketConnector();  
  2. connector.getFilterChain().addLast(“codec”, new ProtocolCodecFilter(new XmlCodecFactory(Charset.forName(charsetName), null, sertType)));  
  3. //指定线程池  
  4. connector.getFilterChain().addLast(“executor”, new ExecutorFilter());  
  5. //指定业务处理类  
  6. connector.setHandler(this);  
        SocketConnector connector = new NioSocketConnector();
        connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new XmlCodecFactory(Charset.forName(charsetName), null, sertType)));
        //指定线程池
        connector.getFilterChain().addLast("executor", new ExecutorFilter());
        //指定业务处理类
        connector.setHandler(this);

在IoHandler中定义了一些事件方法,比如messageReceived,sessionOpend,sessionCreated,exceptionCaught等,用户只需要在方法内部实现对应的处理逻辑即可。

心跳机制:

mina自身带的心跳机制好处在于,它附加了处理,让心跳消息不会传到业务层,在底层就完成了。

事件模型:

MINA可以看成是事件驱动的。通常在网络通讯中,可以将整个过程划分为几个基本的阶段,如建立连接、数据通信、关闭连接。

数据通信一般包括数据的发送和接收,由于在通信过程中,可能要多次发送和接收数据,以进行不同的业务交互。

不可能一直都接收和发送数据,因此就有Idle出现,在MINA中,如果在设定的时间内没有数据发送或接收,那么就会触发一个Idle事件。


附录:对与协议的理解,摘自ppt

http协议
对应于应用层
tcp协议
对应于传输层
ip协议
对应于网络层
三者本质上没有可比性。  何况HTTP协议是基于TCP连接的。
TCP/IP是传输层协议,主要解决数据如何在网络中传输;而HTTP是应用层协议,主要解决如何包装数据。
我们在传输数据时,可以只使用传输层(TCP/IP),但是那样的话,由于没有应用层,便无法识别数据内容,如果想要使传输的数据有意义,则必须使用应用层协议,应用层协议很多,有HTTP、FTP、TELNET等等,也可以自己定义应用层协议。WEB使用HTTP作传输层协议,以封装HTTP文本信息,然后使用TCP/IP做传输层协议将它发送到网络上。

Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP 协议。 

这也就不难理解为什么有些内部的系统调用采用socket,而不是http。

本身web的这种系统,HTTP已经将报文信息封装好了。各种JEE的WEB框架,都能够直接获取报文中的信息,而socket方式,可以双方很方便的自己定义报文的内容,加密方式等等。

URL:应用层

SOCKET
:网络传输层

Socket(套接字)

是一种基于网络传输层的远程进程间通信编程接口,有操作系统提供一个套接字包含,主机名、端口号两个部分。其中端口号是0~65535之间的一个整数。通常小于1024的端口号被统一分配给特定的网络服务,如ftp服务,21;http服务, 80;SMTP服务,25;POP3服务,110;telnet服务,23等等

套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。

应用层通过传输层进行数据通信时,TCP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要通过同一个
TCP协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了套接字(Socket)接口。

由于通常情况下Socket连接就是TCP连接,因此Socket连接一旦建立,通信双方即可开始相互发送数据内容,直到双方连接断开。但在实际网络应用中,客户端到服务器之间的通信往往需要穿越多个中间节点,例如路由器、网关、防火墙等,大部分防火墙默认会关闭长时间处于非活跃状态的连接而导致
Socket 连接断连,因此需要通过轮询告诉网络,该连接处于活跃状态。
而HTTP连接使用的是“请求—响应”的方式,不仅在请求时需要先建立连接,而且需要客户端向服务器发出请求后,服务器端才能回复数据。

很多情况下,需要服务器端主动向客户端推送数据,保持客户端与服务器数据的实时与同步。此时若双方建立的是Socket连接,服务器就可以直接将数据传送给客户端;若双方建立的是HTTP连接,则服务器需要等到客户端发送一次请求后才能将数据传回给客户端,因此,客户端定时向服务器端发送连接请求,不仅可以保持在线,同时也是在“询问”服务器是否有新的数据,如果有就将数据传给客户端。

相关 [mina 网络 通信] 推荐:

MINA网络通信框架

- - 淘宝网通用产品团队博客
Apache MINA 2是一个开发高性能和高可伸缩性网络应用程序的网络应用框架. 它提供了一个抽象的事件驱动的异步API,可以使用TCP/IP、UDP/IP、串口和虚拟机内部的管道等传输方式. Apache MINA 2可以作为开发网络应用程序的一个良好基础. Mina 的API 将真正的网络通信与我们的应用程序隔离开来,你只需要关心你要发送、.

socket通信框架mina使用详解(一)

- - CSDN博客编程语言推荐文章
1.mina框架基于tcp/ip,udp/ip协议栈的通信框架. 2.mina框架的执行流程:. mina框架客户端与服务器端的执行流程一致,不同的是:Ioservice的client端实现是Ioconnector,server端是IoAcceptor..  * 客户端 iohandler.  * mina框架中客户端与服务器端的执行流程一致,.

底层架构-远程通讯-Mina

- - BlogJava-首页技术区
    Apache Mina是一个能够帮助用户开发高性能和高伸缩性网络应用程序的框架. 它通过Java nio技术基于TCP/IP和UDP/IP协议提供了抽象的、事件驱动的、异步的API. 1、  基于Java nio的TCP/IP和UDP/IP实现. 基于RXTX的串口通信(RS232). 2、通过filter接口实现扩展,类似于Servlet filters.

Android之网络通信

- - 博客园_首页
由于一个项目的需要,我研究了一下android的网络通信方式,大体和java平台的很相似. android平台也提供了很多的API供开发者使用,请按示例图:. 首先,介绍一下通过http包工具进行通信,分get和post两种方式,两者的区别是:. 1,post请求发送数据到服务器端,而且数据放在html header中一起发送到服务器url,数据对用户不可见,get请求是把参数值加到url的队列中,这在一定程度上,体现出post的安全性要比get高.

Netty实现网络通信

- - 互联网 - ITeye博客
原文同步至  http://www.waylau.com/netty-chat/. Netty 是一个 Java NIO 客户端服务器框架,使用它可以快速简单地开发网络应用程序,比如服务器和客户端的协议. Netty 大大简化了网络程序的开发过程比如 TCP 和 UDP 的 socket 服务的开发.

Mina、Netty、Twisted一起学:实现简单的TCP服务器

- - CSDN博客推荐文章
MINA、Netty、Twisted为什么放在一起学习. 首先,不妨先看一下他们官方网站对其的介绍:. (Twisted官网的文案不专业啊,居然不写asynchronous). 从上面简短的介绍中,就可以发现它们的共同特点:event-driven以及asynchronous. 它们都是 事件驱动、异步的网络编程框架.

Kubernetes Service iptables 网络通信验证

- - 三点水
Kubernetes gives Pods their own IP addresses and a single DNS name for a setof Pods, and can load-balance across them.. K8s Service会为每个 Pod 都设置一个它自己的 IP,并为一组 Pod 提供一个统一的 DNS 域名,还可以提供在它们间做负载均衡的能力.

InstantBird – 即时通信软件新秀 | 小众软件 > 网络工具

- 翼翔 - 小众软件 - Appinn
迅鸟(InstantBird)是东里二狗最近迷上的 Win/Lin/Mac 跨平台 IM 客户端,界面清爽如出狱人员的发型,系统资源占用则轻如鸿毛. 软件自带功能紧凑有限,但支持第三方扩展,具有极高可玩性和定制性. 如果你对冷门软件有兴趣,或者只是忍不了 Pidgin 的傻鸟图标,Instantbird 绝对值得一试.

高性能、高并发网络通信系统的架构设计

- - CSDN博客推荐文章
    随着互联网和物联网的高速发展,使用网络的人数和电子设备的数量急剧增长,其也对互联网后台服务程序提出了更高的性能和并发要求. 本文的主要目的是阐述如何进行高并发、高性能通信系统的架构设计,以及这样的系统需要用到的常用技术,但不对其中的技术细节进行讨论和实现. 本篇只起抛砖引玉的之效,如有更好的设计方案和思路,望您不舍赐教.

网络

- 火锅土豆 - 科学松鼠会
本文地址(转载请注明出处): 复制.