- 浏览: 513224 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
fatherican:
写的好。
Netty 4 源码分析——EventExecutor -
hong52533:
大哥,请问你用 groovy Httpbuilder post ...
groovy 操作http请求 -
DEMONU:
能详细讲讲代码实现就更好了
Activemq中的KahaDB消息日志的恢复机制 -
plmmmmlq:
爱死你了,困惑我几天的问题终于解决了。自定义dialog中加载 ...
解决Android帧动画在Oncreate中启动只显示第一帧 -
517505440:
org.springframework.beans.facto ...
Apache XBean 简单介绍
这两天看了下Mina和Netty的源码,想比较来说Mina的结构简洁易懂。Mina和Netty出自同一人,而Netty是作者对Mina的重构版,改进了很多。如果学习网络编程的话,个人建议从Mina开始,学完Mina后再看Netty,学习曲线会变得很平滑;同时还能深刻理解到作者改进点。
先看下Mina的结构图,如果之前做过java的web开发,熟悉servlet规范,看到这个结构图,会觉得非常亲切。这个结构描述了基本的网络开发结构。
好了,说了那么多还是先分析代码吧。Mina的客户端和服务端开发会略有不同,因为java网络编程的本身就是如此。我们先从分析服务器端开发入手。这里引用了Mina example中的Timer server,它的逻辑非常简单,就是接收到客户端的请求后,返回服务器的当前时间。
TimerServerHandler.java
开启服务器
1、先创建一个IoAcceptor实例,这里创建的是一个基于tcp的Java NIO版的IoAccptor
2、往FilterChain中追加了 LoggingFilter 和TextLineCodecFactory,LoggingFilter 可以对客户端的请求和服务器端的响应日志记录。TextLineCodecFactory 是一个协议编码解码器的工厂,就是将字节流与java中的String之间的相互转换。后面会详细介绍。
3、添加一个TimerServerHandler实例。TimeServerHandler 处理的逻辑就是在接收到客户端发送过来的字符串信息后,判断如果是quit,关闭与客户端的链接。不是的就返回服务器的当前时间的字符串。
4、设置一些IoSession的可配属性
5、绑定到一个端口上,开始监听客户端的请求。
上面我们只写了一个TimerServerHandler,并在messageReceived 方法中定义了自己的业务处理就轻松的完成了一个服务器端的开发,而不用去关心底层的链接和I/O处理,这就是mina的魅力所在,让开发人员从处理容易出错的I/O操作中解放出来。
现在我们逐个分析代码中出现的一些类和方法。先看一个IoService的继承体系。Mina提供了丰富的实现,支持很多协议,IoService的继承体系没有下面简单。简单起见,上面的图中值画出了Server端的结构,分析IoServeric先从IoAcceptor入手,而且就分析我们熟悉的java nio相关的类。
IoAcceptor是IoService在服务器端的一个抽象。先从接口的功能开始分析:
从接口的方法上分析可以了解到IoService的主要功能:
1、获取链接通信的元数据
2、IoService维护一个IoServiceListener的列表,IoServiceListener顾名思义,就是对IoService相关的事件进行监听。
3、关闭链接
4、一个IoService对应有一个IoHandler
5、IoService维护这一个IoSession的map
6、一个IoService对应一个FilterChain
7、支持广播功能
8、管理IoSession的中的数据结构
9、统计功能
IoAcceptor 在IoService基础上扩展了绑定和解绑SocketAddress的功能。
SocketAcceptor 在IoAcceptor的基础上将SocketAddress 具体化到InetSocketAddress,同时将IoSessionConfig具体化到SocketSessionConfig。提供了reuseaddress 和backlog的设置。关于backlog在SocketServer中的文档描述是
backlog requested maximum length of the queue of incoming connections.
抽象类分析:
AbstractIoService 提供了IoService中的一些默认实现。
从AbstractIoService 构造函数来分析可以得知
1、AbstractIoService中只定义了上面的构成函数,没有显式定义无参构造函数,所以在子类的初始化在肯定会调用super(IoSessionConifg,Executor),再从上面构造函数前面的判断来看,IoSessionConfig,TransportMetadata都是由子类构造函数传入。Executor 参数子类可传可不传,不传默认Executors.newCachedThreadPool();创建。
2、IoServiceListener 列表的管理交给了IoServiceListenerSupport去处理。并添加了一个IoService激活事件的监听器。
3、创建了一个ExceptionMonitor实例
4、定义了构造Acceptor处理线程名称的逻辑
构造函数之外,AbstractIoService 也定义了一些默认实现
1、IoFilterChain 默认交给DefaultIoFilterChainBuilder 创建
2、IoSessionDataStructureFactory 默认实现为 DefaultIoSessionDataStructureFactory
3、实现了dispose的基本逻辑,为什么说是基本逻辑呢?因为dispose调用的 dispose0方法是交由子类去实现的
4、实现了broadcast
AbstractIoAcceptor 继承自AbstractIoService并实现了IoAcceptor接口,主要的实现有:
1、增加一个可配置的SocketAddress 列表 defaultLocalAddresses ,以及这个列表的只读版本
2、增加一个已绑定的SocketAddress 列表
3、增加一个disconnectOnUnbind 配置,指定在Unbind时是否断掉与客户端的链接
4、实现了bind的基本逻辑,更具体的逻辑在bindInternal中交由子类去实现
5、实现了unbind的基本逻辑,更具体的逻辑在unbind0中交由子类实现
AbstractPollingIoAcceptor<T extends AbstractIoSession, H>
泛参H在子类NioSocketAcceptor中替换为ServerSocketChannel,泛参T替换为NioSession。这样便于分析后面的代码。
主要实现了bind,accept,dispose ServerSocket的基本逻辑。父类AbstractIoService中的Executor主要用于执行ServerSocket的accept逻辑。一旦与客户端建立连接后,之后的I/O操作将交由IoProcessor去处理。关于ServerSocketChannel 的 select,open,close,accept都交由子类实现
私有构造函数定义了IoProcessor实例由外部注入,并初始化seelectable标记为true。具体的init()逻辑由子类去实现。
其他几个重载的构造函数注入默认IoProcessor为SimpleIoProcessorPool实例
提供了一个轮询策略的Acceptor的实现
NioSocketAcceptor
基于tcp协议的java nio版IoAcceptor实现,到这里已经实现所有的网络I/O操作。
先看下Mina的结构图,如果之前做过java的web开发,熟悉servlet规范,看到这个结构图,会觉得非常亲切。这个结构描述了基本的网络开发结构。
- IoService 服务端和客户端I/O 操作的抽象,服务端为IoAcceptor,客户端为IoConnector
- IoSession 封装了服务端与客服端连接的会话信息
- IoFilterChain IoFilter处理链
- IoFilter 对服务端和客户端交互的数据做处理
- IoHandler 业务处理
好了,说了那么多还是先分析代码吧。Mina的客户端和服务端开发会略有不同,因为java网络编程的本身就是如此。我们先从分析服务器端开发入手。这里引用了Mina example中的Timer server,它的逻辑非常简单,就是接收到客户端的请求后,返回服务器的当前时间。
TimerServerHandler.java
public class TimeServerHandler extends IoHandlerAdapter { @Override public void messageReceived(IoSession session, Object message) throws Exception { String msg = (String) message; if ("quit".equals(msg.trim())) { System.out.println("client " + session.getRemoteAddress() + " quited!"); session.close(false); return; } Date date = new Date(); session.write(date.toString()); System.out.println("message written..."); } }
开启服务器
private static final int SERVER_PORT = 8888; public static void main(String[] args) throws IOException { IoAcceptor acceptor = new NioSocketAcceptor(); acceptor.getFilterChain().addLast("logging", new LoggingFilter()); acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8")))); acceptor.setHandler(new TimeServerHandler()); acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10); acceptor.getSessionConfig().setReadBufferSize(2048); acceptor.bind(new InetSocketAddress(SERVER_PORT)); }
1、先创建一个IoAcceptor实例,这里创建的是一个基于tcp的Java NIO版的IoAccptor
2、往FilterChain中追加了 LoggingFilter 和TextLineCodecFactory,LoggingFilter 可以对客户端的请求和服务器端的响应日志记录。TextLineCodecFactory 是一个协议编码解码器的工厂,就是将字节流与java中的String之间的相互转换。后面会详细介绍。
3、添加一个TimerServerHandler实例。TimeServerHandler 处理的逻辑就是在接收到客户端发送过来的字符串信息后,判断如果是quit,关闭与客户端的链接。不是的就返回服务器的当前时间的字符串。
4、设置一些IoSession的可配属性
5、绑定到一个端口上,开始监听客户端的请求。
上面我们只写了一个TimerServerHandler,并在messageReceived 方法中定义了自己的业务处理就轻松的完成了一个服务器端的开发,而不用去关心底层的链接和I/O处理,这就是mina的魅力所在,让开发人员从处理容易出错的I/O操作中解放出来。
现在我们逐个分析代码中出现的一些类和方法。先看一个IoService的继承体系。Mina提供了丰富的实现,支持很多协议,IoService的继承体系没有下面简单。简单起见,上面的图中值画出了Server端的结构,分析IoServeric先从IoAcceptor入手,而且就分析我们熟悉的java nio相关的类。
IoAcceptor是IoService在服务器端的一个抽象。先从接口的功能开始分析:
public interface IoService { TransportMetadata getTransportMetadata(); void addListener(IoServiceListener listener); void removeListener(IoServiceListener listener); boolean isDisposing(); boolean isDisposed(); void dispose(); void dispose(boolean awaitTermination); IoHandler getHandler(); void setHandler(IoHandler handler); Map<Long, IoSession> getManagedSessions(); int getManagedSessionCount(); IoSessionConfig getSessionConfig(); IoFilterChainBuilder getFilterChainBuilder(); void setFilterChainBuilder(IoFilterChainBuilder builder); DefaultIoFilterChainBuilder getFilterChain(); boolean isActive(); long getActivationTime(); Set<WriteFuture> broadcast(Object message); IoSessionDataStructureFactory getSessionDataStructureFactory(); void setSessionDataStructureFactory(IoSessionDataStructureFactory sessionDataStructureFactory); int getScheduledWriteBytes(); int getScheduledWriteMessages(); IoServiceStatistics getStatistics(); }
从接口的方法上分析可以了解到IoService的主要功能:
1、获取链接通信的元数据
2、IoService维护一个IoServiceListener的列表,IoServiceListener顾名思义,就是对IoService相关的事件进行监听。
3、关闭链接
4、一个IoService对应有一个IoHandler
5、IoService维护这一个IoSession的map
6、一个IoService对应一个FilterChain
7、支持广播功能
8、管理IoSession的中的数据结构
9、统计功能
IoAcceptor 在IoService基础上扩展了绑定和解绑SocketAddress的功能。
SocketAcceptor 在IoAcceptor的基础上将SocketAddress 具体化到InetSocketAddress,同时将IoSessionConfig具体化到SocketSessionConfig。提供了reuseaddress 和backlog的设置。关于backlog在SocketServer中的文档描述是
引用
backlog requested maximum length of the queue of incoming connections.
抽象类分析:
AbstractIoService 提供了IoService中的一些默认实现。
protected AbstractIoService(IoSessionConfig sessionConfig, Executor executor) { if (sessionConfig == null) { throw new IllegalArgumentException("sessionConfig"); } if (getTransportMetadata() == null) { throw new IllegalArgumentException("TransportMetadata"); } if (!getTransportMetadata().getSessionConfigType().isAssignableFrom( sessionConfig.getClass())) { throw new IllegalArgumentException("sessionConfig type: " + sessionConfig.getClass() + " (expected: " + getTransportMetadata().getSessionConfigType() + ")"); } listeners = new IoServiceListenerSupport(this); listeners.add(serviceActivationListener); this.sessionConfig = sessionConfig; ExceptionMonitor.getInstance(); if (executor == null) { this.executor = Executors.newCachedThreadPool(); createdExecutor = true; } else { this.executor = executor; createdExecutor = false; } threadName = getClass().getSimpleName() + '-' + id.incrementAndGet(); }
从AbstractIoService 构造函数来分析可以得知
1、AbstractIoService中只定义了上面的构成函数,没有显式定义无参构造函数,所以在子类的初始化在肯定会调用super(IoSessionConifg,Executor),再从上面构造函数前面的判断来看,IoSessionConfig,TransportMetadata都是由子类构造函数传入。Executor 参数子类可传可不传,不传默认Executors.newCachedThreadPool();创建。
2、IoServiceListener 列表的管理交给了IoServiceListenerSupport去处理。并添加了一个IoService激活事件的监听器。
3、创建了一个ExceptionMonitor实例
4、定义了构造Acceptor处理线程名称的逻辑
构造函数之外,AbstractIoService 也定义了一些默认实现
1、IoFilterChain 默认交给DefaultIoFilterChainBuilder 创建
2、IoSessionDataStructureFactory 默认实现为 DefaultIoSessionDataStructureFactory
3、实现了dispose的基本逻辑,为什么说是基本逻辑呢?因为dispose调用的 dispose0方法是交由子类去实现的
public final void dispose(boolean awaitTermination) { if (disposed) { return; } synchronized (disposalLock) { if (!disposing) { disposing = true; try { dispose0(); } catch (Exception e) { ExceptionMonitor.getInstance().exceptionCaught(e); } } } if (createdExecutor) { ExecutorService e = (ExecutorService) executor; e.shutdownNow(); if (awaitTermination) { //Thread.currentThread().setName(); try { LOGGER.debug("awaitTermination on {} called by thread=[{}]", this, Thread.currentThread().getName()); e.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS); LOGGER.debug("awaitTermination on {} finished", this); } catch (InterruptedException e1) { LOGGER.warn("awaitTermination on [{}] was interrupted", this); // Restore the interrupted status Thread.currentThread().interrupt(); } } } disposed = true; }
4、实现了broadcast
public final Set<WriteFuture> broadcast(Object message) { // Convert to Set. We do not return a List here because only the // direct caller of MessageBroadcaster knows the order of write // operations. final List<WriteFuture> futures = IoUtil.broadcast(message, getManagedSessions().values()); return new AbstractSet<WriteFuture>() { @Override public Iterator<WriteFuture> iterator() { return futures.iterator(); } @Override public int size() { return futures.size(); } }; }
AbstractIoAcceptor 继承自AbstractIoService并实现了IoAcceptor接口,主要的实现有:
1、增加一个可配置的SocketAddress 列表 defaultLocalAddresses ,以及这个列表的只读版本
2、增加一个已绑定的SocketAddress 列表
3、增加一个disconnectOnUnbind 配置,指定在Unbind时是否断掉与客户端的链接
4、实现了bind的基本逻辑,更具体的逻辑在bindInternal中交由子类去实现
public final void bind(Iterable<? extends SocketAddress> localAddresses) throws IOException { if (isDisposing()) { throw new IllegalStateException("Already disposed."); } if (localAddresses == null) { throw new IllegalArgumentException("localAddresses"); } List<SocketAddress> localAddressesCopy = new ArrayList<SocketAddress>(); for (SocketAddress a: localAddresses) { checkAddressType(a); localAddressesCopy.add(a); } if (localAddressesCopy.isEmpty()) { throw new IllegalArgumentException("localAddresses is empty."); } boolean activate = false; synchronized (bindLock) { synchronized (boundAddresses) { if (boundAddresses.isEmpty()) { activate = true; } } if (getHandler() == null) { throw new IllegalStateException("handler is not set."); } try { Set<SocketAddress> addresses = bindInternal( localAddressesCopy ); synchronized (boundAddresses) { boundAddresses.addAll(addresses); } } catch (IOException e) { throw e; } catch (RuntimeException e) { throw e; } catch (Throwable e) { throw new RuntimeIoException( "Failed to bind to: " + getLocalAddresses(), e); } } if (activate) { getListeners().fireServiceActivated(); } }
5、实现了unbind的基本逻辑,更具体的逻辑在unbind0中交由子类实现
public final void unbind(Iterable<? extends SocketAddress> localAddresses) { if (localAddresses == null) { throw new IllegalArgumentException("localAddresses"); } boolean deactivate = false; synchronized (bindLock) { synchronized (boundAddresses) { if (boundAddresses.isEmpty()) { return; } List<SocketAddress> localAddressesCopy = new ArrayList<SocketAddress>(); int specifiedAddressCount = 0; for (SocketAddress a: localAddresses ) { specifiedAddressCount++; if ((a != null) && boundAddresses.contains(a) ) { localAddressesCopy.add(a); } } if (specifiedAddressCount == 0) { throw new IllegalArgumentException( "localAddresses is empty." ); } if (!localAddressesCopy.isEmpty()) { try { unbind0(localAddressesCopy); } catch (RuntimeException e) { throw e; } catch (Throwable e) { throw new RuntimeIoException( "Failed to unbind from: " + getLocalAddresses(), e ); } boundAddresses.removeAll(localAddressesCopy); if (boundAddresses.isEmpty()) { deactivate = true; } } } } if (deactivate) { getListeners().fireServiceDeactivated(); } }
AbstractPollingIoAcceptor<T extends AbstractIoSession, H>
泛参H在子类NioSocketAcceptor中替换为ServerSocketChannel,泛参T替换为NioSession。这样便于分析后面的代码。
主要实现了bind,accept,dispose ServerSocket的基本逻辑。父类AbstractIoService中的Executor主要用于执行ServerSocket的accept逻辑。一旦与客户端建立连接后,之后的I/O操作将交由IoProcessor去处理。关于ServerSocketChannel 的 select,open,close,accept都交由子类实现
私有构造函数定义了IoProcessor实例由外部注入,并初始化seelectable标记为true。具体的init()逻辑由子类去实现。
private AbstractPollingIoAcceptor(IoSessionConfig sessionConfig, Executor executor, IoProcessor<NioSession> processor, boolean createdProcessor) { super(sessionConfig, executor); if (processor == null) { throw new IllegalArgumentException("processor"); } //注入IoProcessor对象 this.processor = processor; this.createdProcessor = createdProcessor; try { //初始化设置交给子类实现 init(); // 构造函数中设置标记为true,后面便可以s selectable = true; } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new RuntimeIoException("Failed to initialize.", e); } finally { if (!selectable) { try { destroy(); } catch (Exception e) { ExceptionMonitor.getInstance().exceptionCaught(e); } } } }
其他几个重载的构造函数注入默认IoProcessor为SimpleIoProcessorPool实例
protected AbstractPollingIoAcceptor(IoSessionConfig sessionConfig, Class<? extends IoProcessor<T>> processorClass, int processorCount) { this(sessionConfig, null, new SimpleIoProcessorPool<T>(processorClass, processorCount), true); }
提供了一个轮询策略的Acceptor的实现
private class Acceptor implements Runnable { public void run() { // nHandles 表示已经open的ServerSocketChannel数量 int nHandles = 0; //无限循环,接收客户端的链接请求,并处理,直到所有opened ServerSocketChannel都被close while (selectable) { try { //轮询获得 int selected = select(); //open ServerSocketChannel并增加nHandles nHandles += registerHandles(); if (selected > 0) { // We have some connection request, let's process // them here. processHandles(selectedHandles()); } //close ServerSocketChannel并减少nHandles nHandles -= unregisterHandles(); //没有ServerSocketChannel在监听客户端的请求,跳出循环 if (nHandles == 0) { synchronized (lock) { if (registerQueue.isEmpty() && cancelQueue.isEmpty()) { acceptor = null; break; } } } } catch (ClosedSelectorException cse) { break; } catch (Throwable e) { ExceptionMonitor.getInstance().exceptionCaught(e); try { Thread.sleep(1000); } catch (InterruptedException e1) { ExceptionMonitor.getInstance().exceptionCaught(e1); } } } if (selectable && isDisposing()) { selectable = false; try { if (createdProcessor) { processor.dispose(); } } finally { try { synchronized (disposalLock) { if (isDisposing()) { destroy(); } } } catch (Exception e) { ExceptionMonitor.getInstance().exceptionCaught(e); } finally { disposalFuture.setDone(); } } } } private void processHandles(Iterator<ServerSocketChannel> handles) throws Exception { while (handles.hasNext()) { ServerSocketChannel handle = handles.next(); handles.remove(); // 接收客户端的请求,建立链接,返回对链接信息封装后的IoSession NioSession session = accept(processor, handle); if (session == null) { break; } // 初始化IoSession信息 initSession(session, null, null); // 将连接的I/O(read,write,close etc)交给Processor线程处理 session.getProcessor().add(session); } } } private int registerHandles() { //开启一个无限循环,不断从registerQueue队列中获取AcceptorOperationFuture,直到registerQueue为空 for (;;) { AcceptorOperationFuture future = registerQueue.poll(); if (future == null) { return 0; } // 创建一个临时的map以便在打开socket的时候出现异常及时释放资源 Map<SocketAddress, ServerSocketChannel> newHandles = new ConcurrentHashMap<SocketAddress, ServerSocketChannel>(); List<SocketAddress> localAddresses = future.getLocalAddresses(); try { for (SocketAddress a : localAddresses) { //遍历所有的SocketAddress,open ServerSocketChannel ServerSocketChannel handle = open(a); newHandles.put(localAddress(handle), handle); } // 未出现异常,将所有open成功的ServerSocketChannel放到boundHandles boundHandles.putAll(newHandles); // 设置异步处理完成 future.setDone(); // 返回open成功的ServerSocketChannel的数量 return newHandles.size(); } catch (Exception e) { future.setException(e); } finally { //在open时出现了异常,释放相应的 资源 if (future.getException() != null) { for (ServerSocketChannel handle : newHandles.values()) { try { close(handle); } catch (Exception e) { ExceptionMonitor.getInstance().exceptionCaught(e); } } wakeup(); } } } } // 关闭ServerSocketChannel private int unregisterHandles() { int cancelledHandles = 0; // 循环从cancelQueue队列中获取待关闭的ServerSocketChannel,直到cancelQueue清空 for (;;) { AcceptorOperationFuture future = cancelQueue.poll(); if (future == null) { break; } for (SocketAddress a : future.getLocalAddresses()) { // 先从已绑定的ServerSocketChannel列表中移除 ServerSocketChannel handle = boundHandles.remove(a); if (handle == null) { continue; } try { //关闭ServerSocketChannel,真正的实现交给子类 close(handle); wakeup(); } catch (Throwable e) { ExceptionMonitor.getInstance().exceptionCaught(e); } finally { cancelledHandles++; } } // future.setDone(); } //返回已关闭的ServerSocketChannel的数量 return cancelledHandles; }
NioSocketAcceptor
基于tcp协议的java nio版IoAcceptor实现,到这里已经实现所有的网络I/O操作。
//默认的ServerSocket的backlog属性为50 private int backlog = 50; // 默认reuseAddress为false private boolean reuseAddress = false; // java nio 中的selector,状态改变多线程可见 private volatile Selector selector; //构造函数出入的默认IoSessionConfig实现为DefaultSocketSessionConfig public NioSocketAcceptor() { super(new DefaultSocketSessionConfig(), NioProcessor.class); ((DefaultSocketSessionConfig) getSessionConfig()).init(this); } // 如果你熟悉java nio,看到这些代码是否有种豁然开朗的感觉呢?原来是这样的啊! @Override protected void init() throws Exception { selector = Selector.open(); } @Override protected void destroy() throws Exception { if (selector != null) { selector.close(); } } public TransportMetadata getTransportMetadata() { return NioSocketSession.METADATA; } @Override protected NioSession accept(IoProcessor<NioSession> processor, ServerSocketChannel handle) throws Exception { SelectionKey key = handle.keyFor(selector); if ((key == null) || (!key.isValid()) || (!key.isAcceptable()) ) { return null; } SocketChannel ch = handle.accept(); if (ch == null) { return null; } return new NioSocketSession(this, processor, ch); } @Override protected ServerSocketChannel open(SocketAddress localAddress) throws Exception { // Creates the listening ServerSocket ServerSocketChannel channel = ServerSocketChannel.open(); boolean success = false; try { // This is a non blocking socket channel channel.configureBlocking(false); // Configure the server socket, ServerSocket socket = channel.socket(); // Set the reuseAddress flag accordingly with the setting socket.setReuseAddress(isReuseAddress()); // and bind. socket.bind(localAddress, getBacklog()); // Register the channel within the selector for ACCEPT event channel.register(selector, SelectionKey.OP_ACCEPT); success = true; } finally { if (!success) { close(channel); } } return channel; } @Override protected void close(ServerSocketChannel handle) throws Exception { SelectionKey key = handle.keyFor(selector); if (key != null) { key.cancel(); } handle.close(); } @Override protected void wakeup() { selector.wakeup(); }
相关推荐
### Mina2源码分析——核心模块解析 #### 概述 Mina2是一个高性能、可扩展的网络应用框架,支持多种传输协议如TCP、UDP等,并提供了丰富的API供开发者使用。本文旨在深入剖析Mina2的核心部分,帮助读者更好地理解和...
在这个“MINA源码分析,内涵类的讲解”中,我们将深入探讨MINA的核心组件和设计模式,以便更好地理解和利用这个强大的框架。 首先,我们需要了解MINA的基础架构。MINA的核心是`IoService`接口,它定义了服务端和...
在深入解析Mina源码的过程中,我们可以从以下几个关键知识点入手: 1. **Mina的过滤器机制实现**: Mina的核心设计理念之一是过滤器链(Filter Chain),它借鉴了Servlet的过滤器模型。每个过滤器都可以在数据传输...
通过阅读和分析`apache-mina-2.0.16`的源码,我们可以深入理解MINA的设计思想,学习如何构建高效的网络服务,并能根据自己的需求定制和扩展MINA的功能。对于想要从事网络编程或系统架构设计的开发者来说,研究MINA...
在分析"apache-mina-2.0.4"源码时,我们可以深入理解其设计理念、架构以及核心组件。 1. **MINA的设计理念** MINA的核心理念是异步非阻塞I/O,它利用Java NIO(New I/O)库来实现高效的网络通信。通过非阻塞I/O,...
在MINA源码中,我们可以看到以下关键组件: 1. **Session**:这是MINA中的核心概念,代表了网络连接。Session负责管理连接状态,并提供读写数据的方法。 2. **Filter Chain**:MINA采用过滤器链模式来处理网络事件...
Mina2源码分析 Mina2框架源码剖析是 Java 编程语言中一个流行的网络编程框架,用于构建高性能、可扩展的网络应用程序。该框架核心包包括 org.apache.mina.core.service, org.apache.mina.core.session, org.apache....
`IoService`是Mina2框架的核心接口,它为服务器端的连接接受和客户端的连接发起提供了抽象。`IoService`包含了以下关键特性: 1. `TransportMetadata`提供了底层网络服务提供商的信息,如NIO。 2. `IoSessionConfig`...
### mina2.0源码svn地址解析与详细介绍 #### 一、Mina2.0简介 Mina(Multi-threaded IO Network Architecture)是Apache软件基金会的一个开源项目,旨在为开发人员提供一个易于使用的高性能网络应用程序框架。Mina...
6. **Nio**与**Aio**:Mina2支持两种不同的I/O模型——NIO(非阻塞I/O)和AIO(异步I/O)。NIO适用于高并发场景,而AIO在低延迟和高吞吐量的应用中表现出色。 通过深入研究Mina2的源码,我们可以了解到如何优化网络...
### MINA源码走读与实例 #### 一、MINA概述 **MINA**(**M**ulti **I**nterface **N**etwork **A**pplication)是Apache组织下的一款开源网络通信框架,它主要针对TCP/IP、UDP/IP协议栈提供了高效的封装和扩展能力...
2. **分析源码**:通过阅读MINA的源码,了解其内部处理流程,如读写事件的处理、过滤器链的工作方式等。 3. **编写简单的应用**:从例子入手,创建一个简单的MINA服务器和客户端,理解它们之间的通信机制。 4. **...
这个压缩包"mina学习资料与源码分析"包含了帮助你快速入门Mina、深入理解其工作原理和API的资源。下面,我们将深入探讨Mina的核心概念、功能以及如何利用它来开发网络应用。 Mina源于Java社区,其全称为“Minimal ...
通过分析源码,我们可以看到Mina如何优雅地将网络编程的复杂性封装起来,让开发者可以更专注于应用的业务层面。同时,通过心跳机制,我们能够实时检测网络状况,确保服务的稳定性和可靠性。 总的来说,Mina框架提供...
通过深入分析Mina2.0的源码,我们可以了解到其内部的事件驱动模型、网络通信机制以及如何通过过滤器和处理器来处理网络请求。这有助于我们更好地理解和利用Mina框架来开发高并发、高性能的网络应用。
此外,源码分析还能帮助你掌握如何自定义Filter和Codec,以满足特定的应用场景需求。 总之,MINA 2.0.9源码为开发者提供了一个深入学习网络编程和异步I/O的好资源,通过研究和实践,开发者可以提升自己的网络应用...
mina新手案例,mina新手教程源码 mina+springboot最简单的案例。用的IDEA * mina服务端 * 1、添加@Controller注解和 @PostConstruct注解,代表启动springboot项目时也调用该类下的该方法, * 启动springboot项目...
通过对Mina源码的学习,开发者不仅能理解其设计理念,还能掌握如何优化网络通信应用,提高系统的稳定性和性能。此外,学习Mina也能帮助开发者更好地理解Java NIO和网络编程的底层原理,对于提升专业技能非常有帮助。
标题"mina2 源码 mina"暗示我们将探讨MINA2的源代码,这是一个非常有价值的资源,对于理解MINA的工作原理、学习如何构建网络应用程序以及定制MINA的行为非常有用。MINA的源码包含了丰富的注释和示例,可以帮助开发者...