`
Donald_Draper
  • 浏览: 980023 次
社区版块
存档分类
最新评论

MINA 多路复用协议编解码器工厂二(多路复用协议解码器)

    博客分类:
  • Mina
阅读更多
MINA 多路复用协议编解码器工厂一(多路复用协议编码器):
http://donald-draper.iteye.com/blog/2377170
引言:
   上一篇文章我们看了多路复用协议编码器,今天我们来看一下多路复用协议解码器,先来回顾一下:
   多路复用的协议编码器添加消息编码器,如果参数为消息类型和消息编码器类型,添加消息类型与默认构造消息编码工厂到消息编码器Map映射type2encoderFactory;如果参数为消息类型和消息编码器实例,添加消息类型与单例消息编码器工厂到消息编码器Map映射type2encoderFactory。多路复用的协议编码器编码消息,首先从会话获取消息编码器状态,从消息编码器状态获取消息对应的编码器(先从消息编码器查找,没有则从消息编码器映射type2encoder查找),如果没有消息对应的解码,则查找消息父接口和类对应的编码器,编码消息。
我们从多路复用协议编解码工厂DemuxingProtocolCodecFactory的定义开始
public class DemuxingProtocolCodecFactory
    implements ProtocolCodecFactory
{
    private final DemuxingProtocolEncoder encoder = new DemuxingProtocolEncoder();//多路复用的协议编码器
    private final DemuxingProtocolDecoder decoder = new DemuxingProtocolDecoder();//多路复用的协议解码器
    public DemuxingProtocolCodecFactory()
    {
    }
    public ProtocolEncoder getEncoder(IoSession session)
        throws Exception
    {
        return encoder;
    }
    public ProtocolDecoder getDecoder(IoSession session)
        throws Exception
    {
        return decoder;
    }
    ...
}

从上面来看多路复用协议编解码工厂,包含一个多路复用的协议编码器和解码器。在往下看之前,我们先看一下多路复用的协议编码器和解码器。
我们来看多路复用协议解码器:
public class DemuxingProtocolDecoder extends CumulativeProtocolDecoder
{
    private final AttributeKey STATE = new AttributeKey(getClass(), "state");
    private MessageDecoderFactory decoderFactories[];//消息解码器工厂集
    private static final Class EMPTY_PARAMS[] = new Class[0];
     public DemuxingProtocolDecoder()
    {
        decoderFactories = new MessageDecoderFactory[0];
    }
}

先看看一下消息解码器工厂和消息解码器的定义
//消息解码器工厂
//MessageDecoderFactory
public interface MessageDecoderFactory
{
    public abstract MessageDecoder getDecoder()
        throws Exception;
}

//消息解码器MessageDecoder
/**
 * Decodes specific messages.
 * 
 * @author The Apache Directory Project (mina-dev@directory.apache.org)
 * @version $Rev$, $Date$
 * 
 * @see DemuxingProtocolCodecFactory
 * @see MessageDecoderFactory
 */
public interface MessageDecoder {
    /**
     * Represents a result from {@link #decodable(IoSession, ByteBuffer)} and
     * {@link #decode(IoSession, ByteBuffer, ProtocolDecoderOutput)}.  Please
     * refer to each method's documentation for detailed explanation.
    #decodable和#decode方法的返回结果
     */
    static MessageDecoderResult OK = MessageDecoderResult.OK;

    /**
     * Represents a result from {@link #decodable(IoSession, ByteBuffer)} and
     * {@link #decode(IoSession, ByteBuffer, ProtocolDecoderOutput)}.  Please
     * refer to each method's documentation for detailed explanation.
      #decodable和#decode方法的返回结果
     */
    static MessageDecoderResult NEED_DATA = MessageDecoderResult.NEED_DATA;

    /**
     * Represents a result from {@link #decodable(IoSession, ByteBuffer)} and
     * {@link #decode(IoSession, ByteBuffer, ProtocolDecoderOutput)}.  Please
     * refer to each method's documentation for detailed explanation.
      #decodable和#decode方法的返回结果
     */
    static MessageDecoderResult NOT_OK = MessageDecoderResult.NOT_OK;

    /**
     * Checks the specified buffer is decodable by this decoder.
     * 检查解码器是否可解buffer中的数据
     * @return {@link #OK} if this decoder can decode the specified buffer.
     #OK可以解码buffer中的数据
     *         {@link #NOT_OK} if this decoder cannot decode the specified buffer.
    #NOT_OK表示解码器不可解码buffer数据
     *         {@link #NEED_DATA} if more data is required to determine if the
     *         specified buffer is decodable ({@link #OK}) or not decodable
     *         {@link #NOT_OK}.
      #NEED_DATA表示需要更多的数据来确认解码器是否可以解码buffer数据
     */
    MessageDecoderResult decodable(IoSession session, ByteBuffer in);

    /**
     * Decodes binary or protocol-specific content into higher-level message objects.
     * MINA invokes {@link #decode(IoSession, ByteBuffer, ProtocolDecoderOutput)}
     * method with read data, and then the decoder implementation puts decoded
     * messages into {@link ProtocolDecoderOutput}.
     * 解码二级制或协议数据为上层消息对象。mina调用#decode方法解码读到的数据,解码将解码后的消息
     放到协议解码输出ProtocolDecoderOutput的消息队列中,待flush消息给下一个过滤器
     * @return {@link #OK} if you finished decoding messages successfully.
     #OK解码消息成功
     *         {@link #NEED_DATA} if you need more data to finish decoding current message.
     #NEED_DATA,需要更多的数据完成消息解码
     *         {@link #NOT_OK} if you cannot decode current message due to protocol specification violation.
     * #NOT_OK由于内容与协议不一致,不能解码当前消息,        
     * @throws Exception if the read data violated protocol specification 
     */
    MessageDecoderResult decode(IoSession session, ByteBuffer in,
            ProtocolDecoderOutput out) throws Exception;

    /**
     * Invoked when the specified <tt>session</tt> is closed while this decoder was
     * parsing the data.  This method is useful when you deal with the protocol which doesn't
     * specify the length of a message such as HTTP response without <tt>content-length</tt>
     * header. Implement this method to process the remaining data that
     * {@link #decode(IoSession, ByteBuffer, ProtocolDecoderOutput)} method didn't process
     * completely.
     * 当会话关闭,同时解码器正在解码消息,调用此方法。这个方法在需要处理的消息没有固定长度的情况下,非常
     有用,比如Http响应,没有内容长度头部。此方法用于解码器没有解码完的数据。
     * @throws Exception if the read data violated protocol specification
     */
    void finishDecode(IoSession session, ProtocolDecoderOutput out)
            throws Exception;
}

从上可以看出消息解码器MessageDecoder,有3个方法分别为,decodable方法用于判断解码器是否可以解码buffer数据,返回值(MessageDecoderResult)#OK表示可以解码buffer中的数据,#NOT_OK表示解码器不可解码buffer数据, #NEED_DATA表示需要更多的数据来确认解码器是否可以解码buffer数据;decode用于解码buffer数据,返回值#OK表示解码消息成功,#NEED_DATA,表示需要更多的数据完成消息解码,#NOT_OK由于内容与协议不一致,不能解码当前消息;finishDecode主要是处理#decode方法没有解码完的数据。
我们在回到多路复用协议解码器
//DemuxingProtocolDecoder
//添加消息解码器
  public void addMessageDecoder(Class decoderClass)
    {
        if(decoderClass == null)
            throw new IllegalArgumentException("decoderClass");
        try
        {
            decoderClass.getConstructor(EMPTY_PARAMS);
        }
        catch(NoSuchMethodException e)
        {
            throw new IllegalArgumentException("The specified class doesn't have a public default constructor.");
        }
        boolean registered = false;
	//如果消息解码器类型为MessageDecoder
        if(org/apache/mina/filter/codec/demux/MessageDecoder.isAssignableFrom(decoderClass))
        {
	    //添加解码器工厂,到多路复用协议解码器工厂组decoderFactories
            addMessageDecoder(((MessageDecoderFactory) (new DefaultConstructorMessageDecoderFactory(decoderClass))));
            registered = true;
        }
        if(!registered)
            throw new IllegalArgumentException((new StringBuilder()).append("Unregisterable type: ").append(decoderClass).toString());
        else
            return;
    }

来看这一句
//添加解码器工厂,到多路复用协议解码器工厂集decoderFactories
addMessageDecoder(((MessageDecoderFactory) (new DefaultConstructorMessageDecoderFactory(decoderClass))));

 public void addMessageDecoder(MessageDecoderFactory factory)
    {
        if(factory == null)
        {
            throw new IllegalArgumentException("factory");
        } else
        {
	    //将解码器工厂集长度增+1,将解码器工厂放入解码器工厂集
            MessageDecoderFactory decoderFactories[] = this.decoderFactories;
            MessageDecoderFactory newDecoderFactories[] = new MessageDecoderFactory[decoderFactories.length + 1];
            System.arraycopy(decoderFactories, 0, newDecoderFactories, 0, decoderFactories.length);
            newDecoderFactories[decoderFactories.length] = factory;
            this.decoderFactories = newDecoderFactories;
            return;
        }
    }

再来看以下默认构造消息解码器工厂DefaultConstructorMessageDecoderFactory
 private static class DefaultConstructorMessageDecoderFactory
        implements MessageDecoderFactory
    {
        private final Class decoderClass;//解码器类
        private DefaultConstructorMessageDecoderFactory(Class decoderClass)
        {
            if(decoderClass == null)
                throw new IllegalArgumentException("decoderClass");
            if(!org/apache/mina/filter/codec/demux/MessageDecoder.isAssignableFrom(decoderClass))
            {
                throw new IllegalArgumentException("decoderClass is not assignable to MessageDecoder");
            } else
            {
                this.decoderClass = decoderClass;
                return;
            }
        }
	 public MessageDecoder getDecoder()
            throws Exception
        {
            return (MessageDecoder)decoderClass.newInstance();//创建解码器实例
        }
    }

再看多路复用协议解码器添加解码器实例
    public void addMessageDecoder(MessageDecoder decoder)
    {
        //添加单例解码器工厂,到多路复用协议解码器工厂集decoderFactories
        addMessageDecoder(((MessageDecoderFactory) (new SingletonMessageDecoderFactory(decoder))));
    }

再来看单例解码器工厂SingletonMessageDecoderFactory
  private static class SingletonMessageDecoderFactory
        implements MessageDecoderFactory
    {
        private final MessageDecoder decoder;
        private SingletonMessageDecoderFactory(MessageDecoder decoder)
        {
            if(decoder == null)
            {
                throw new IllegalArgumentException("decoder");
            } else
            {
                this.decoder = decoder;
                return;
            }
        public MessageDecoder getDecoder()
        {
            return decoder;
        }
        
        }
}  

从添加解码器到多路复用协议解码器可以看出,如果添加的解码器为Class,则添加默认构造消息解码器工厂到到多路复用协议解码器工厂集decoderFactories;如果添加的解码器为实例,则添加单例解码器工厂,到多路复用协议解码器工厂集。
由于多路复用协议解码器继承DemuxingProtocolDecoder于累计协议解码器CumulativeProtocolDecoder
我们来看实际的解码工作:
protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out)
        throws Exception
    {
        State state;
        MessageDecoder decoders[];
        int undecodables;
        int i;
	//从会话获取解码器状态
        state = getState(session);
        if(state.currentDecoder != null)
            break MISSING_BLOCK_LABEL_250;
	//获取状态解码器集
        decoders = state.decoders;
        undecodables = 0;
        i = decoders.length - 1;
_L3:
        if(i < 0) goto _L2; else goto _L1
_L1:
       //遍历状态解码器集
        MessageDecoder decoder;
        int limit;
        int pos;
        decoder = decoders[i];
        limit = in.limit();
        pos = in.position();
	//测试解码器是否可以解码buffer数据
        MessageDecoderResult result = decoder.decodable(session, in);
        in.position(pos);
        in.limit(limit);
        break MISSING_BLOCK_LABEL_103;
        Exception exception;
        exception;
        in.position(pos);
        in.limit(limit);
        throw exception;
        if(result == MessageDecoder.OK)
        {
	    //可以解码,则会话状态的解码器为decoder
            state.currentDecoder = decoder;
            break; /* Loop/switch isn't completed */
        }
        if(result == MessageDecoder.NOT_OK)
        {
            undecodables++;
            continue; /* Loop/switch isn't completed */
        }
        if(result != MessageDecoder.NEED_DATA)//需要数据判断解码器是否可以解码
            throw new IllegalStateException((new StringBuilder()).append("Unexpected decode result (see your decodable()): ").append(result).toString());
        i--;
          goto _L3
_L2:
        if(undecodables == decoders.length)
        {
	    //没有解码器,可以解码buffer数据
            String dump = in.getHexDump();
            in.position(in.limit());
            ProtocolDecoderException e = new ProtocolDecoderException((new StringBuilder()).append("No appropriate message decoder: ").append(dump).toString());
            e.setHexdump(dump);
            throw e;
        }
        if(state.currentDecoder == null)
            return false;
        MessageDecoderResult result;
	//会话状态当前解码器,解码buffer
        result = state.currentDecoder.decode(session, in, out);
        if(result != MessageDecoder.OK)
            break MISSING_BLOCK_LABEL_282;
        state.currentDecoder = null;
        return true;
	//解码器完成解码消息,需要数据
        if(result == MessageDecoder.NEED_DATA)
            return false;
        try
        {
            if(result == MessageDecoder.NOT_OK)
            {
	        //buffer数据与协议不一致
                state.currentDecoder = null;
                throw new ProtocolDecoderException("Message decoder returned NOT_OK.");
            } else
            {
                state.currentDecoder = null;
                throw new IllegalStateException((new StringBuilder()).append("Unexpected decode result (see your decode()): ").append(result).toString());
            }
        }
        catch(Exception e)
        {
            state.currentDecoder = null;
            throw e;
        }
    }

上面有一点我们要关注:
//从会话获取解码器状态
state = getState(session);

先看一下State的定义
private class State
    {

        private final MessageDecoder decoders[];//消息解码器集
        private MessageDecoder currentDecoder;//当前消息解码器
        final DemuxingProtocolDecoder this$0;//多路复用协议解码器
        private State()
            throws Exception
        {
            this$0 = DemuxingProtocolDecoder.this;
            super();
            MessageDecoderFactory decoderFactories[] = DemuxingProtocolDecoder.this.decoderFactories;
            decoders = new MessageDecoder[decoderFactories.length];
	    //遍历多路复用协议解码的解码器工厂集,从工厂获取解码器,添加到消息解码器集decoders
            for(int i = decoderFactories.length - 1; i >= 0; i--)
                decoders[i] = decoderFactories[i].getDecoder();

        }
    }

//从会话获取解码器状态
private State getState(IoSession session)
        throws Exception
    {
        //先从会话获取解码器状态属性,如果解码器状态为空,则创建解码器状态,并添加到会话中
        State state = (State)session.getAttribute(STATE);
        if(state == null)
        {
            state = new State();
            State oldState = (State)session.setAttributeIfAbsent(STATE, state);
            if(oldState != null)
                state = oldState;
        }
        return state;
    }

从上面可以看出多路复用协议解码器,解码消息的过程为,首先从会话获取解码器状态集,遍历解码器集,找到可以解码消息的解码器,并赋给会话解码器状态当前解码器currentDecoder,最后由currentDecoder解码消息。
再来看剩余方法:
//解码解码器没有处理的数据
public void finishDecode(IoSession session, ProtocolDecoderOutput out)
        throws Exception
    {
        super.finishDecode(session, out);
        State state = getState(session);
        MessageDecoder currentDecoder = state.currentDecoder;
        if(currentDecoder == null)
        {
            return;
        } else
        {
	    //委托给会话当前解码器
            currentDecoder.finishDecode(session, out);
            return;
        }
    }
    //释放解码器资源
    public void dispose(IoSession session)
        throws Exception
    {
        super.dispose(session);
        session.removeAttribute(STATE);
    }

至此我们把多路复用协议编解码器看完,现在我们来看多路复用协议编解码器工的其他方法:
//添加消息编码器,直接委托给内部的多路复用协议编码器
  public void addMessageEncoder(Class messageType, Class encoderClass)
    {
        encoder.addMessageEncoder(messageType, encoderClass);
    }
    public void addMessageEncoder(Class messageType, MessageEncoder encoder)
    {
        this.encoder.addMessageEncoder(messageType, encoder);
    }
    public void addMessageEncoder(Class messageType, MessageEncoderFactory factory)
    {
        encoder.addMessageEncoder(messageType, factory);
    }
    public void addMessageEncoder(Iterable messageTypes, Class encoderClass)
    {
        Class messageType;
        for(Iterator iterator = messageTypes.iterator(); iterator.hasNext(); addMessageEncoder(messageType, encoderClass))
            messageType = (Class)iterator.next();

    }
    public void addMessageEncoder(Iterable messageTypes, MessageEncoder encoder)
    {
        Class messageType;
        for(Iterator iterator = messageTypes.iterator(); iterator.hasNext(); addMessageEncoder(messageType, encoder))
            messageType = (Class)iterator.next();

    }
    public void addMessageEncoder(Iterable messageTypes, MessageEncoderFactory factory)
    {
        Class messageType;
        for(Iterator iterator = messageTypes.iterator(); iterator.hasNext(); addMessageEncoder(messageType, factory))
            messageType = (Class)iterator.next();

    }
//添加消息解码器,直接委托给内部的多路复用协议解码器
    public void addMessageDecoder(Class decoderClass)
    {
        decoder.addMessageDecoder(decoderClass);
    }
    public void addMessageDecoder(MessageDecoder decoder)
    {
        this.decoder.addMessageDecoder(decoder);
    }
    public void addMessageDecoder(MessageDecoderFactory factory)
    {
        decoder.addMessageDecoder(factory);
    }

总结:
    消息解码器MessageDecoder,有3个方法分别为,decodable方法用于判断解码器是否可以解码buffer数据,返回值(MessageDecoderResult)#OK表示可以解码buffer中的数据,#NOT_OK表示解码器不可解码buffer数据, #NEED_DATA表示需要更多的数据来确认解码器是否可以解码buffer数据;decode用于解码buffer数据,返回值#OK表示解码消息成功,#NEED_DATA,表示需要更多的数据完成消息解码,#NOT_OK由于内容与协议不一致,不能解码当前消息;finishDecode主要是处理#decode方法没有解码完的数据。添加解码器到多路复用协议解码器,如果添加的解码器为Class,则添加默认构造消息解码器工厂到到多路复用协议解码器工厂集decoderFactories;如果添加的解码器为实例,则添加单例解码器工厂,到多路复用协议解码器工厂集。多路复用协议解码器,解码消息的过程为,首先从会话获取解码器状态集,遍历解码器集,找到可以解码消息的解码器,并赋给会话解码器状态当前解码器currentDecoder,最后由currentDecoder解码消息。
      多路复用协议编解码器工厂内部关联一个多路复用协议编码器和解码器器,添加消息编码器和解码器到多路复用协议编解码器工厂,实际是添加多路复用协议编解码器中。

附:
//MessageDecoderResult消息解码结果
/**
 * Represents results from {@link MessageDecoder}.
 * @author The Apache Directory Project (mina-dev@directory.apache.org)
 * @version $Rev$, $Date$
 * @see MessageDecoder
 */
public class MessageDecoderResult {
    private final String name;
    private MessageDecoderResult(String name) {
        this.name = name;
    }
    public static MessageDecoderResult OK = new MessageDecoderResult("OK");
    public static MessageDecoderResult NEED_DATA = new MessageDecoderResult(
            "NEED_DATA");
    public static MessageDecoderResult NOT_OK = new MessageDecoderResult(
            "NOT_OK");
    public String toString() {
        return name;
    }
}
0
0
分享到:
评论

相关推荐

    mina 多路分离解码

    例如,如果我们的应用使用了某种特定的二进制协议,我们可以创建一个解码器来解析这种协议的数据包,并将其转换为对应的Java对象。 多路分离解码的工作流程大致如下: 1. 数据进入mina服务端,首先经过IoFilter链...

    Mina开发之客户端

    4. **创建和添加Protocol Codec**: 配置一个编解码器工厂,例如TCPCodecFactory,将其添加到过滤器链中。 5. **设置Event Handler**: 定义一个实现了IoHandler接口的类,处理客户端的网络事件。 6. **发送和接收...

    Mina 框架研究与实现

    Mina通过其内置的协议编解码器,为这些操作提供了高度封装,大大提高了代码的复用性和维护性。 #### 总结 Mina框架以其卓越的性能和灵活的架构,成为了开发高性能网络应用程序的理想选择。它不仅简化了底层I/O和...

    JAVA mina 框架源码

    4. **协议编解码**:Mina提供了多种编码解码工厂,如LineDelimiter codec用于按行分割数据,或者ProtocolDecoderOutput和ProtocolEncoderInput接口,用于自定义复杂的编解码策略。 5. **线程模型**:Mina的线程模型...

    mina的高级使用,mina文件图片传送,mina发送文件,mina报文处理,mina发送xml和json

    通过使用I/O多路复用技术,如NIO(非阻塞I/O),Mina能够高效地管理多个连接,而无需为每个连接创建单独的线程。这极大地降低了系统资源的消耗,提高了服务器的并发能力。 2. **Mina文件图片传送** 在Mina中,我们...

    Apache Mina 入门Demo

    4. **协议编码和解码**:Mina提供了多种编码器和解码器,用于将用户数据转换为网络传输格式,如ByteToMessageDecoder和MessageToByteEncoder。你可以根据需要自定义这些编码器和解码器以适应特定的协议。 5. **事件...

    apache下的mina框架的源码

    4. **异步IO(Asynchronous IO)**:MINA使用Java NIO(非阻塞I/O)库,支持多路复用,允许在单线程中处理多个连接,提高了系统资源利用率和性能。 在`apache-mina-2.0.5`这个压缩包中,你可以找到以下关键组件和...

    Mina in Action preview

    1. **Mina架构**:理解Mina的核心架构,包括I/O多路复用模型(如NIO和Epoll)以及事件驱动的设计,这些设计使得Mina能够处理大量并发连接。 2. **Filter Chain**:Mina的过滤器链机制是其核心特性之一,它允许...

    mina服务器实例

    1. **事件驱动模型**:Mina采用I/O多路复用技术,如NIO(非阻塞I/O)和EPOLL,通过事件驱动模型处理网络连接,有效提升了并发处理能力。 2. **过滤器链**:Mina的过滤器链是其核心设计之一,它允许开发者插入自定义...

    Mina框架+常用JAR包

    1. **异步I/O模型**:Mina采用NIO(非阻塞I/O)模式,通过多路复用器和回调机制,提高了系统在高并发场景下的性能。 2. **丰富的协议库**:内建对多种网络协议的支持,方便开发者快速实现各种网络服务。 3. **过滤器...

    mina2技术知识

    MINA 提供了多种预定义的解码器和编码器,比如LineBasedFrameDecoder用于按行处理数据,ByteToMessageDecoder和MessageToByteEncoder则用于字节到消息对象和反向转换。 4. **Handler**:Handler 是业务逻辑的容器,...

    apache mina socket

    2. **I/O多路复用**:Mina利用Java NIO(非阻塞I/O)库,支持I/O多路复用,使得单个线程可以处理多个连接,提高了系统资源利用率。 3. **Filter Chain**:Mina的过滤器链是其核心设计之一,允许开发者插入自定义的...

    mina2.0.3源代码

    在“apache-mina-2.0.3”这个压缩包中,包含了MINA框架的源代码,开发者可以通过阅读源码来深入理解MINA的工作原理,定制自己的网络应用,或者参与MINA的二次开发。这个版本的MINA经过了广泛的测试和优化,稳定性和...

    apache mina-spring 服务端程序

    在Mina中,Socket通信是通过一个事件驱动模型实现的,该模型基于I/O多路复用技术,如Java的NIO(Non-blocking I/O)。这种模型可以处理大量的并发连接,且资源消耗较低。Spring的集成使得开发者可以通过声明式的方式...

    Java-mina实现推送

    例如,如果你使用自定义的二进制或XML格式,你需要提供相应的编解码器。 3. **整合Spring:** Spring框架可以帮助我们更好地管理和组织Mina的组件。可以将`IoHandler`实例配置为Spring Bean,然后在Mina的`...

    MINA长连接框架实现通讯

    8. **性能优化**:MINA框架允许开发者进行各种性能优化,例如调整缓冲区大小、选择合适的编码/解码器、合理设置线程池大小等,以适应不同规模的网络应用需求。 综上所述,MINA长连接框架在实现服务器与Android...

    基于MINA构建简单高性能的NIO应用.pdf

    3. **MINA的时间服务器示例**:如何使用MINA搭建一个基础的时间服务器,包括创建服务端监听器、定义协议解码器和编码器、处理客户端连接请求和发送时间响应等步骤。 4. **多客户端处理**:MINA如何通过Selector和多...

    mina源代码学习提供下载

    4. **过滤器链**:MINA引入了过滤器的概念,数据在传输过程中会经过一系列过滤器,每个过滤器可以执行特定的操作,如编码、解码、日志记录等。这种设计使得模块化和复用变得简单。 5. **多线程支持**:MINA支持多...

    mina2.0.9jar包下载

    4. **过滤器链**:Mina的过滤器链机制允许开发者插入自定义的过滤器,对网络通信进行预处理和后处理,如数据编码解码、安全认证等。 5. **丰富的协议支持**:Mina内建了对多种网络协议的支持,如HTTP、FTP、SSL/TLS...

Global site tag (gtag.js) - Google Analytics