`

网络通讯应用mina研究一

阅读更多

mina研究一

Apache Mina IoAcceptor与IoConnector
 

简介

Apache mina是一个介于应用程序与网络之间的NIO框架,它使程序员从繁琐的网络操作中解脱出来,花更多的时间在业务处理上。

如下图所示,mina分为三层

1、IOService层:处理IO操作

2、IOFilter层:过滤器链,日志处理、字节变换、对象转换等操作

3、IOHandler层:真正的处理业务逻辑的地方

IOService层根据不同的角色又分为IOAcceptor和IOConnector,分别用于接受连接与请求连接操作。

IOAcceptor

上图是IOAcceptor的类图,IOAcceptor相当于是对ServerSocketChannel的封装,最重要的两个操作是绑定与接受连接,IOService接口中有多个重载的bind方法

  1. public interface IoAcceptor extends IoService {          
  2.     void bind() throws IOException;     
  3.     void bind(SocketAddress localAddress) throws IOException;         
  4.     void bind(SocketAddress firstLocalAddress, SocketAddress... addresses) throws IOException;     
  5.     void bind(Iterable<? extends SocketAddress> localAddresses) throws IOException;  
  6. }     
其方法的实现在抽象类AbstractIOAcceptor的bind方法中,这个方法在做了参数检查等操作后,将真正的绑定操作交给抽象方法bindInternal来完成。对于bindInternal有基于TCP/IP,UDP/IP,VMPipe三种实现,以TCP/IP为例来看绑定过程
  1. protected final Set<SocketAddress> bindInternal(  
  2.          List<? extends SocketAddress> localAddresses) throws Exception {  
  3.      // Create a bind request as a Future operation. When the selector  
  4.      // have handled the registration, it will signal this future.  
  5.      AcceptorOperationFuture request = new AcceptorOperationFuture(  
  6.              localAddresses);  
  7.   
  8.      // adds the Registration request to the queue for the Workers  
  9.      // to handle  
  10.      registerQueue.add(request);  
  11.   
  12.      // creates the Acceptor instance and has the local  
  13.      // executor kick it off.  
  14.      startupAcceptor();  
  15.        
  16.      // As we just started the acceptor, we have to unblock the select()  
  17.      // in order to process the bind request we just have added to the   
  18.      // registerQueue.  
  19.      wakeup();  
  20.        
  21.      // Now, we wait until this request is completed.  
  22.      request.awaitUninterruptibly();  
  23.   
  24.      if (request.getException() != null) {  
  25.          throw request.getException();  
  26.      }  
  27.   
  28.      // Update the local addresses.  
  29.      // setLocalAddresses() shouldn't be called from the worker thread  
  30.      // because of deadlock.  
  31.      Set<SocketAddress> newLocalAddresses = new HashSet<SocketAddress>();  
  32.        
  33.      for (H handle:boundHandles.values()) {  
  34.          newLocalAddresses.add(localAddress(handle));  
  35.      }  
  36.   
  37.      return newLocalAddresses;  
  38.  }  

主要干了以下几件事情:

1、将绑定请求放入registerQueue中

2、启动Acceptor,从Acceptor类的run方法可以看到,这一步会阻塞在Acceptor选择器的选择操作中

3、调用wakeup让选择器返回

4、等待请求处理完成,这一步会阻塞在ready变量中,当ready变量为true时才会返回,当接受连接后ready会被设置为true.

现在重点看一下Acceptor的run方法

  1. public void run() {  
  2.         ......  
  3.     while (selectable) {  
  4.         try {  
  5.             int selected = select();  
  6.             nHandles += registerHandles();  
  7.             if (nHandles == 0) {  
  8.                 acceptorRef.set(null);  
  9.   
  10.                 if (registerQueue.isEmpty() && cancelQueue.isEmpty()) {  
  11.                     assert (acceptorRef.get() != this);  
  12.                     break;  
  13.                 }  
  14.                   
  15.                 if (!acceptorRef.compareAndSet(nullthis)) {  
  16.                     assert (acceptorRef.get() != this);  
  17.                     break;  
  18.                 }  
  19.                   
  20.                 assert (acceptorRef.get() == this);  
  21.             }  
  22.   
  23.             if (selected > 0) {  
  24.                 processHandles(selectedHandles());  
  25.             }  
  26.   
  27.             // check to see if any cancellation request has been made.  
  28.             nHandles -= unregisterHandles();  
  29.         } catch (...) {  
  30.         ...  
  31.     }  
  32.   
  33.     // Cleanup all the processors, and shutdown the acceptor. set ready=true  
  34. }  
(1)、selector被wakeup唤醒后,调用registerHandles方法从registerQueue中取出请求依次调用open方法
  1. protected ServerSocketChannel open(SocketAddress localAddress)  
  2.            throws Exception {  
  3.        // Creates the listening ServerSocket  
  4.        ServerSocketChannel channel = ServerSocketChannel.open();  
  5.          
  6.        boolean success = false;  
  7.          
  8.        try {  
  9.            // This is a non blocking socket channel  
  10.            channel.configureBlocking(false);  
  11.          
  12.            // Configure the server socket,  
  13.            ServerSocket socket = channel.socket();  
  14.              
  15.            // Set the reuseAddress flag accordingly with the setting  
  16.            socket.setReuseAddress(isReuseAddress());  
  17.              
  18.            // and bind.  
  19.            socket.bind(localAddress, getBacklog());  
  20.              
  21.            // Register the channel within the selector for ACCEPT event  
  22.            channel.register(selector, SelectionKey.OP_ACCEPT);  
  23.            success = true;  
  24.        } finally {  
  25.            if (!success) {  
  26.                close(channel);  
  27.            }  
  28.        }  
  29.        return channel;  
  30.    }  
open方法完成了ServerSocket的绑定和注册
(2)、从(1)中可以知道selector上注册了ServerSocketChannel的OP_ACCEPT键,注册后nHandles==0,selected==0,进行下一次循环,同样是阻塞在select方法上

(3)、当连接到来时,select方法返回,selected>0,执行processHandles方法

  1. private void processHandles(Iterator<H> handles) throws Exception {  
  2.             while (handles.hasNext()) {  
  3.                 H handle = handles.next();  
  4.                 handles.remove();  
  5.   
  6.                 // Associates a new created connection to a processor,  
  7.                 // and get back a session  
  8.                 S session = accept(processor, handle);  
  9.                   
  10.                 if (session == null) {  
  11.                     break;  
  12.                 }  
  13.   
  14.                 initSession(session, nullnull);  
  15.   
  16.                 // add the session to the SocketIoProcessor  
  17.                 session.getProcessor().add(session);  
  18.             }  
  19.         }  
该方法在完成真正的接受连接操作后,创建session并扔到processor中,后续的工作交给processor来完成。每个session中其实有一个SocketChannel,这个socketChannel实际上是被注册到了processor的selector上。注册代码在NioProcessor类中可以找到
  1. protected void init(NioSession session) throws Exception {  
  2.     SelectableChannel ch = (SelectableChannel) session.getChannel();  
  3.     ch.configureBlocking(false);  
  4.     session.setSelectionKey(ch.register(selector, SelectionKey.OP_READ,  
  5.             session));  
  6. }  

整个Acceptor的实现就讲解完了,总结一下:Acceptor线程专门负责接受连接,在其上有一个selector,轮询是否有连接建立上来,当有连接建立上来,调用ServerSocketChannel.accept方法来接受连接,这个方法返回一个session对象,然后将这个session对象加入processor中,由processor遍历每个session来完成真正的IO操作。processor上也有一个selector与一个Processor线程,selector用于轮询session,Processor线程处理每个session的IO操作。

IOConnector

IOConnector的类图如下:

IOConnector的设计与IOAcceptor几乎完全一样,唯一不同的是与Acceptor线程对应的是Connector线程,在完成连接操作后也是扔了一个session对象到Processor中。

关于Processor与Session后续再分析......

分享到:
评论

相关推荐

    socket通讯和mina应用

    Socket通讯和MINA应用是Java网络编程中的两个关键概念,它们在开发分布式系统、网络服务和客户端应用程序中扮演着重要角色。这篇博文将深入探讨这两个主题,并通过一个名为"testMina"的压缩包文件来展示实际应用。 ...

    Mina 框架研究与实现

    在Mina框架下,客户端与服务器端的每一次通讯都经过精心设计的过滤器组件和业务Handler的处理,最终转化为字节流在网络中传输。这一过程涉及到编码和解码两个核心步骤。编码是将对象转换为二进制数据包,进而形成...

    Mina通讯中间件

    **Mina通讯中间件** Mina(全称Java MinA,即Minimum Architecture)是一个高性能、...通过深入研究Mina,开发者不仅可以提升网络编程能力,还能更好地理解和应用NIO技术,从而设计出更加高效、稳定的服务器端应用。

    Mina小Demo聊天工具

    总结来说,Mina小Demo是一款结合了Mina的强大网络通信能力与Swing易用界面的示例应用,对于Java开发者来说,无论是学习网络编程还是GUI设计,都是一个很好的实践案例。通过深入研究其源码,我们可以更深入地理解Java...

    mina通讯源代码

    Mina,全称为Apache MINA (Multipurpose Infrastructure for Network Applications),是一个由Apache软件基金会开发的网络应用框架,主要用于简化高效、高性能的网络编程。Mina提供了一种与协议无关的抽象层,允许...

    mina客户端服务器简易Demo

    无论是即时通讯应用、文件传输服务,还是其他基于网络的服务,Mina都能提供稳定高效的解决方案。 总的来说,Apache Mina是一个强大的工具,通过学习和实践这个"mina客户端服务器简易Demo",你可以快速掌握其基本...

    mina即时聊天demo

    尽管这个demo仅在控制台环境中运行,但在实际的Android应用中,我们可以将Mina嵌入到Android项目中,实现移动设备间的即时通讯。需要注意的是,由于Android平台的限制,需要适配多线程和网络访问策略。 6. **Demo...

    mina的Android端全套jar

    mina是一个开源的、基于Java NIO的网络通信框架,它为构建高性能、高可靠性的网络应用提供了强大的工具。在Android开发中,mina库可以用于实现高效的服务器与客户端之间的数据传输,尤其适用于需要进行大量网络交互...

    基于MINA框架的高性能短信猫服务平台设计

    MINA框架是一个基于Java的开源网络应用程序框架,它简化了网络应用的开发,帮助开发者创建高性能、高并发的网络应用。在本文中,作者采用Java NIO(New I/O)技术,利用MINA框架的特点来设计和开发一个高性能的短信...

    火星探测模拟系统(使用Mina-2.0)

    火星探测模拟系统是一个高度复杂且创新的工程,它利用了Apache Mina-2.0这一强大的网络应用框架来实现其核心功能。Apache Mina是一个高度可扩展、高性能的开源Java框架,专门设计用于构建网络通信应用程序,如TCP/IP...

    MinaDemos.rar

    通过深入研究并运行这些示例,你可以更好地理解MINA的异步模型,以及如何利用MINA构建高效的网络应用程序。同时,这也有助于你掌握网络编程的基本原理,如套接字编程、多线程处理和网络数据交换。 总结来说,...

    基于Android平台简易即时通讯的研究与设计

    通过合理的架构设计和协议选择,开发者可以构建出高效、安全、易用的即时通讯应用,满足用户的各种需求。随着移动通信技术的发展,即时通讯功能的扩展和集成变得越来越重要,如群聊、位置分享、语音和视频通话等,...

    java网络框架对比报告.pdf

    - **广泛的应用场景**: 适用于多种网络应用,如游戏服务器、即时通讯系统等。 #### 四、Mina与Netty对比 ##### 4.1 框架使用 - **Mina**: 更加注重封装性,易于快速开发。 - **Netty**: 提供更多的定制化选项,...

    基于Android平台的长连接云推送服务设计.pdf

    在探讨基于Android平台的长连接云推送服务设计过程中,主要涉及以下几个关键技术...通过本文的研究,读者可以了解到如何设计、实现并集成一个基于长连接的云推送服务系统,从而为移动应用开发提供即时的通知推送能力。

    基于NIO框架的TeeTime信息平台的设计与实现

    文章利用NIO技术的特点,应用了基于Java NIO的服务器通信框架,具体是反应器模型和Apache的MINA开源框架,设计了信息平台的数据通讯模块。 最后,文章通过并发性能测试的数据比对,得出所研究与设计的TeeTime服务...

    微信小程序demo:在线聊天功能.zip

    【标题】"微信小程序demo:在线聊天功能.zip" 涉及的核心技术是微信小程序的开发,特别是构建一个实现在线聊天功能的应用。微信小程序是一种轻量级的应用开发平台,允许开发者在微信内创建无需下载安装即可使用的...

    微信小程序demo:在线聊天功能

    通过研究MINA-Chat-master这个项目,不仅可以学习到微信小程序的基础开发,还能了解到在线聊天应用的具体实现细节,包括数据传输、状态管理、用户交互等多个方面。这有助于提升开发者在微信小程序领域的实践能力。

Global site tag (gtag.js) - Google Analytics