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

Mina Io监听器接口定义及抽象实现

    博客分类:
  • Mina
阅读更多
Mina IoService接口定义及抽象实现:http://donald-draper.iteye.com/blog/2378271
引言:
    上面我们看了IoService接口的定义及抽象实现,先来回顾一下:
    抽象service关联一个IoHandler处理会话相关事件,关联一个执行器Executor,负责处理io事件的执行,一个会话配置IOsessionConfig,用于service创建会话时,配置会话,一个过滤链构建器IoFilterChainBuilder,用于构建会话的过滤链,会话数据结构工厂,用于创建会话的属性Map和写请求队列,还有service监听器和统计器。抽象service构造,首先检查会话配置和传输元数据,会话配置必须传输元数据的会话配置类型必须相同,即socket(TCP),会话配置为socketSessionConfig,报文通信(UDP),为DatagramSessionConfig;然后将会话创建监听器serviceActivationListener添加监听器管理器IoServiceListenerSupport;初始化会话配置,IO事件执行器executor和异常监视器。初始化会话就是将service会话数据结构工厂的会话属性添加到具体的会话中,将service会话数据结构工厂的写请求队列,设置到具体的会话中,如果是连接请求会话,则将连接结果添加会话属性中。
今天我们我们来看一下IoService的一个分支IoAcceptor:
/**
 * Accepts incoming connection, communicates with clients, and fires events to
 * {@link IoHandler}s.
 接收连接请求,与客户端通信,触发IoHandler相关事件。
 * <p>
 * Please refer to
 * [url=../../../../../xref-examples/org/apache/mina/examples/echoserver/Main.html]EchoServer[/url]
 * example.
 * <p>
 * You should bind to the desired socket address to accept incoming
 * connections, and then events for incoming connections will be sent to
 * the specified default {@link IoHandler}.
 * <p>
 你应该绑定socket地址,以接收连接请求,连接请求事件将会发送个默认的IoHandler。
 * Threads accept incoming connections start automatically when
 * {@link #bind()} is invoked, and stop when {@link #unbind()} is invoked.
 *当IoAcceptor绑定地址时,相关线程将自动开始接收连接请求,当调用#unbind方法,将停止
 线程接收连接请求
 * @author [url=http://mina.apache.org]Apache MINA Project[/url]
 */
public interface IoAcceptor extends IoService {
    /**
     * Returns the local address which is bound currently.  If more than one
     * address are bound, only one of them will be returned, but it's not
     * necessarily the firstly bound address.
     * 返回当前绑定本地地址,当绑定多个地址时,返回其中一个,不需要非是第一个绑定的地址
     * @return The bound LocalAddress
     */
    SocketAddress getLocalAddress();

    /**
     * Returns a {@link Set} of the local addresses which are bound currently.
     * 返回绑定的地址集
     * @return The Set of bound LocalAddresses
     */
    Set<SocketAddress> getLocalAddresses();

    /**
     * Returns the default local address to bind when no argument is specified
     * in {@link #bind()} method.  Please note that the default will not be
     * used if any local address is specified.  If more than one address are
     * set, only one of them will be returned, but it's not necessarily the
     * firstly specified address in {@link #setDefaultLocalAddresses(List)}.
     * 当bind无参方法被调用时,返回一个默认的本地地址。
     * @return The default bound LocalAddress
     */
    SocketAddress getDefaultLocalAddress();

    /**
     * Returns a {@link List} of the default local addresses to bind when no
     * argument is specified in {@link #bind()} method.  Please note that the
     * default will not be used if any local address is specified.
     * 返回默认地址集
     * @return The list of default bound LocalAddresses
     */
    List<SocketAddress> getDefaultLocalAddresses();

    /**
     * Sets the default local address to bind when no argument is specified in
     * {@link #bind()} method.  Please note that the default will not be used
     * if any local address is specified.
     *设置默认socket地址
     * @param localAddress The local addresses to bind the acceptor on
     */
    void setDefaultLocalAddress(SocketAddress localAddress);

    /**
     * Sets the default local addresses to bind when no argument is specified
     * in {@link #bind()} method.  Please note that the default will not be
     * used if any local address is specified.
     设置默认地址集
     * @param firstLocalAddress The first local address to bind the acceptor on
     * @param otherLocalAddresses The other local addresses to bind the acceptor on
     */
    void setDefaultLocalAddresses(SocketAddress firstLocalAddress, SocketAddress... otherLocalAddresses);

    /**
     * Sets the default local addresses to bind when no argument is specified
     * in {@link #bind()} method.  Please note that the default will not be
     * used if any local address is specified.
     * 
     * @param localAddresses The local addresses to bind the acceptor on
     */
    void setDefaultLocalAddresses(Iterable<? extends SocketAddress> localAddresses);

    /**
     * Sets the default local addresses to bind when no argument is specified
     * in {@link #bind()} method.  Please note that the default will not be
     * used if any local address is specified.
     * 
     * @param localAddresses The local addresses to bind the acceptor on
     */
    void setDefaultLocalAddresses(List<? extends SocketAddress> localAddresses);

    /**
     * Returns <tt>true</tt> if and only if all clients are closed when this
     * acceptor unbinds from all the related local address (i.e. when the
     * service is deactivated).
     当且仅当所有客户端关闭,acceptor解绑所有相关本地地址
     * 
     * @return <tt>true</tt> if the service sets the closeOnDeactivation flag
     */
    boolean isCloseOnDeactivation();

    /**
     * Sets whether all client sessions are closed when this acceptor unbinds
     * from all the related local addresses (i.e. when the service is
     * deactivated).  The default value is <tt>true</tt>.
     * 无论所有客户端关闭是否,acceptor是否解绑所有相关本地地址,设置closeOnDeactivation
     * @param closeOnDeactivation <tt>true</tt> if we should close on deactivation
     */
    void setCloseOnDeactivation(boolean closeOnDeactivation);

    /**
     * Binds to the default local address(es) and start to accept incoming
     * connections.
     *绑定默认的socket本地地址,接收连接请求
     * @throws IOException if failed to bind
     */
    void bind() throws IOException;

    /**
     * Binds to the specified local address and start to accept incoming
     * connections.
     *绑定socket本地地址,接收连接请求
     * @param localAddress The SocketAddress to bind to
     * 
     * @throws IOException if failed to bind
     */
    void bind(SocketAddress localAddress) throws IOException;

    /**
     * Binds to the specified local addresses and start to accept incoming
     * connections. If no address is given, bind on the default local address.
     * 绑定socket本地地址,接收连接请求,如果没给给定参数,绑定默认地址
     * @param firstLocalAddress The first address to bind to
     * @param addresses The SocketAddresses to bind to
     * 
     * @throws IOException if failed to bind
     */
    void bind(SocketAddress firstLocalAddress, SocketAddress... addresses) throws IOException;

    /**
     * Binds to the specified local addresses and start to accept incoming
     * connections. If no address is given, bind on the default local address.
     * 绑定socket本地地址,接收连接请求,如果没给给定参数,绑定默认地址
     * @param addresses The SocketAddresses to bind to
     *
     * @throws IOException if failed to bind
     */
    void bind(SocketAddress... addresses) throws IOException;

    /**
     * Binds to the specified local addresses and start to accept incoming
     * connections.
     *绑定socket本地地址,接收连接请求,如果没给给定参数,绑定默认地址
     * @param localAddresses The local address we will be bound to
     * @throws IOException if failed to bind
     */
    void bind(Iterable<? extends SocketAddress> localAddresses) throws IOException;

    /**
     * Unbinds from all local addresses that this service is bound to and stops
     * to accept incoming connections.  All managed connections will be closed
     * if {@link #setCloseOnDeactivation(boolean) disconnectOnUnbind} property
     * is <tt>true</tt>.  This method returns silently if no local address is
     * bound yet.
     解绑service绑定的所有本地socket地址,停止接收,连接请求。如果CloseOnDeactivation参数为
     解绑时,断开连接,则关闭service管理的所有会话。
     */
    void unbind();

    /**
     * Unbinds from the specified local address and stop to accept incoming
     * connections.  All managed connections will be closed if
     * {@link #setCloseOnDeactivation(boolean) disconnectOnUnbind} property is
     * <tt>true</tt>.  This method returns silently if the default local
     * address is not bound yet.
     * 解绑service绑定的所有本地socket地址,停止接收,连接请求。如果CloseOnDeactivation参数为
     解绑时,断开连接,则关闭service管理的所有会话。
     * @param localAddress The local address we will be unbound from
     */
    void unbind(SocketAddress localAddress);

    /**
     * Unbinds from the specified local addresses and stop to accept incoming
     * connections.  All managed connections will be closed if
     * {@link #setCloseOnDeactivation(boolean) disconnectOnUnbind} property is
     * <tt>true</tt>.  This method returns silently if the default local
     * addresses are not bound yet.
     * 解绑service绑定的所有本地socket地址,停止接收,连接请求。如果CloseOnDeactivation参数为
     解绑时,断开连接,则关闭service管理的所有会话。
     * @param firstLocalAddress The first local address to be unbound from
     * @param otherLocalAddresses The other local address to be unbound from
     */
    void unbind(SocketAddress firstLocalAddress, SocketAddress... otherLocalAddresses);

    /**
     * Unbinds from the specified local addresses and stop to accept incoming
     * connections.  All managed connections will be closed if
     * {@link #setCloseOnDeactivation(boolean) disconnectOnUnbind} property is
     * <tt>true</tt>.  This method returns silently if the default local
     * addresses are not bound yet.
     * 解绑service绑定的所有本地socket地址,停止接收,连接请求。如果CloseOnDeactivation参数为
     解绑时,断开连接,则关闭service管理的所有会话。
     * @param localAddresses The local address we will be unbound from
     */
    void unbind(Iterable<? extends SocketAddress> localAddresses);

    /**
     * (Optional) Returns an {@link IoSession} that is bound to the specified
     * <tt>localAddress</tt> and the specified <tt>remoteAddress</tt> which
     * reuses the local address that is already bound by this service.
     返回绑定本地地址和远端socket地址的会话,本地地址,service已绑定,并可以重用
     * <p>
     * This operation is optional.  Please throw {@link UnsupportedOperationException}
     * if the transport type doesn't support this operation.  This operation is
     * usually implemented for connectionless transport types.
     *操作时可选的,如果transport不支持此操作,则可抛出UnsupportedOperationException,
     此操作一般报文通信会实现
     * @param remoteAddress The remote address bound to the service
     * @param localAddress The local address the session will be bound to
     * @throws UnsupportedOperationException if this operation is not supported
     * @throws IllegalStateException if this service is not running.
     * @throws IllegalArgumentException if this service is not bound to the
     *                                  specified <tt>localAddress</tt>.
     * @return The session bound to the the given localAddress and remote address
     */
    IoSession newSession(SocketAddress remoteAddress, SocketAddress localAddress);
}

从IoAcceptor的接口定义可以看,IoAcceptor是将IoService添加了监听连接请求功能。
再来看抽象实现:
/**
 * A base implementation of {@link IoAcceptor}.
 *
 * @author [url=http://mina.apache.org]Apache MINA Project[/url]
 * @org.apache.xbean.XBean
 */
public abstract class AbstractIoAcceptor extends AbstractIoService implements IoAcceptor {
    private final List<SocketAddress> defaultLocalAddresses = new ArrayList<>();//默认绑定的socket地址集
    private final List<SocketAddress> unmodifiableDefaultLocalAddresses = Collections
            .unmodifiableList(defaultLocalAddresses);//包装默认的地址集为不可修改集合
    private final Set<SocketAddress> boundAddresses = new HashSet<>();//绑定地址集
    private boolean disconnectOnUnbind = true;
    /**
     * The lock object which is acquired while bind or unbind operation is performed.
     * Acquire this lock in your property setters which shouldn't be changed while
     * the service is bound.
     */
    protected final Object bindLock = new Object();
    
    /**
     * Constructor for {@link AbstractIoAcceptor}. You need to provide a default
     * session configuration and an {@link Executor} for handling I/O events. If
     * null {@link Executor} is provided, a default one will be created using
     * {@link Executors#newCachedThreadPool()}.
     * 根据会话配置和执行器构造抽象Io接收器
     * @see AbstractIoService#AbstractIoService(IoSessionConfig, Executor)
     * 
     * @param sessionConfig
     *            the default configuration for the managed {@link IoSession}
     * @param executor
     *            the {@link Executor} used for handling execution of I/O
     *            events. Can be <code>null</code>.
     */
    protected AbstractIoAcceptor(IoSessionConfig sessionConfig, Executor executor) {
        super(sessionConfig, executor);
        defaultLocalAddresses.add(null);
    }
}

来看一下地址绑定操作:
  /**
     * {@inheritDoc}
     */
    @Override
    public final void bind() throws IOException {
        bind(getDefaultLocalAddresses());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final void bind(SocketAddress localAddress) throws IOException {
        if (localAddress == null) {
            throw new IllegalArgumentException("localAddress");
        }
        
        List<SocketAddress> localAddresses = new ArrayList<>(1);
        localAddresses.add(localAddress);
        bind(localAddresses);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public final void bind(SocketAddress... addresses) throws IOException {
        if ((addresses == null) || (addresses.length == 0)) {
            bind(getDefaultLocalAddresses());
            return;
        }
        List<SocketAddress> localAddresses = new ArrayList<>(2);

        for (SocketAddress address : addresses) {
            localAddresses.add(address);
        }
        bind(localAddresses);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public final void bind(SocketAddress firstLocalAddress, SocketAddress... addresses) throws IOException {
        if (firstLocalAddress == null) {
            bind(getDefaultLocalAddresses());
        }
        if ((addresses == null) || (addresses.length == 0)) {
            bind(getDefaultLocalAddresses());
            return;
        }
        List<SocketAddress> localAddresses = new ArrayList<>(2);
        localAddresses.add(firstLocalAddress);

        for (SocketAddress address : addresses) {
            localAddresses.add(address);
        }
        bind(localAddresses);
    }
以上的绑定方法,实际由bind(Iterable<? extends SocketAddress> localAddresses)完成。

    /**
     * {@inheritDoc}
     */
    @Override
public final void bind(Iterable<? extends SocketAddress> localAddresses) throws IOException {
        if (isDisposing()) {
            throw new IllegalStateException("The Accpetor disposed is being disposed.");
        }
        if (localAddresses == null) {
            throw new IllegalArgumentException("localAddresses");
        }
        List<SocketAddress> localAddressesCopy = new ArrayList<>();
        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
                    boundAddresses.addAll(addresses);
                }
            } catch (IOException | RuntimeException e) {
                throw e;
            } catch (Exception e) {
                throw new RuntimeIoException("Failed to bind to: " + getLocalAddresses(), e);
            }
        }
        if (activate) {
	   //通知Service监听器,Service已激活
            getListeners().fireServiceActivated();
        }
    }

绑定方法有以下几点要看
 1.
  checkAddressType(a);//检查地址类

 private void checkAddressType(SocketAddress a) {
       //检查绑定的socket地址与传输元数据的地址类型是否相同
        if (a != null && !getTransportMetadata().getAddressType().isAssignableFrom(a.getClass())) {
            throw new IllegalArgumentException("localAddress type: " + a.getClass().getSimpleName() + " (expected: "
                    + getTransportMetadata().getAddressType().getSimpleName() + ")");
        }
    }

 2.
 //完成实际绑定
 Set<SocketAddress> addresses = bindInternal(localAddressesCopy); 

/**
     * Starts the acceptor, and register the given addresses
     * 待子类扩展,启动监听器,注册地址
     * @param localAddresses The address to bind to
     * @return the {@link Set} of the local addresses which is bound actually
     * @throws Exception If the bind failed
     */
protected abstract Set<SocketAddress> bindInternal(List<? extends SocketAddress> localAddresses) throws Exception;

从上面可以看出,绑定地址首先要检查绑定的socket地址与传输元数据的地址类型是否相同,相同则通过bindInternal完成实际的绑定,然后通知Service监听器,Service已激活fireServiceActivated。
再来看地址解绑:
/**
     * {@inheritDoc}
     */
    @Override
    public final void unbind() {
        unbind(getLocalAddresses());
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public final void unbind(SocketAddress localAddress) {
        if (localAddress == null) {
            throw new IllegalArgumentException("localAddress");
        }

        List<SocketAddress> localAddresses = new ArrayList<>(1);
        localAddresses.add(localAddress);
        unbind(localAddresses);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public final void unbind(SocketAddress firstLocalAddress, SocketAddress... otherLocalAddresses) {
        if (firstLocalAddress == null) {
            throw new IllegalArgumentException("firstLocalAddress");
        }
        if (otherLocalAddresses == null) {
            throw new IllegalArgumentException("otherLocalAddresses");
        }

        List<SocketAddress> localAddresses = new ArrayList<>();
        localAddresses.add(firstLocalAddress);
        Collections.addAll(localAddresses, otherLocalAddresses);
        unbind(localAddresses);
    }

上面所有的解绑方法实际通过unbind(Iterable<? extends SocketAddress> localAddresses)方法完成:
  
 /**
     * {@inheritDoc}
     */
    @Override
    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<>();
                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 (Exception e) {
                        throw new RuntimeIoException("Failed to unbind from: " + getLocalAddresses(), e);
                    }
		    //清空绑定地址集合
                    boundAddresses.removeAll(localAddressesCopy);
                    if (boundAddresses.isEmpty()) {
                        deactivate = true;
                    }
                }
            }
        }
        if (deactivate) {
	    //触发Service监听器无效事件
            getListeners().fireServiceDeactivated();
        }
    }

/**
 * Implement this method to perform the actual unbind operation.
 * 待子类实现,具体解绑
 * @param localAddresses The address to unbind from
 * @throws Exception If the unbind failed
 */
protected abstract void unbind0(List<? extends SocketAddress> localAddresses) throws Exception;

从解绑地址方法来看,主要是委托unbind0方法完成实际解绑工作,清空绑定地址集合boundAddresses,触发Service监听器无效事件fireServiceDeactivated。
再来看其他方法,下面这些方法就不讲了,都是set和get操作看看就行:
  /**
     * {@inheritDoc}
     */
    @Override
    public SocketAddress getLocalAddress() {
        Set<SocketAddress> localAddresses = getLocalAddresses();
        if (localAddresses.isEmpty()) {
            return null;
        }

        return localAddresses.iterator().next();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final Set<SocketAddress> getLocalAddresses() {
        Set<SocketAddress> localAddresses = new HashSet<>();

        synchronized (boundAddresses) {
            localAddresses.addAll(boundAddresses);
        }

        return localAddresses;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public SocketAddress getDefaultLocalAddress() {
        if (defaultLocalAddresses.isEmpty()) {
            return null;
        }
        return defaultLocalAddresses.iterator().next();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final void setDefaultLocalAddress(SocketAddress localAddress) {
        setDefaultLocalAddresses(localAddress);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final List<SocketAddress> getDefaultLocalAddresses() {
        return unmodifiableDefaultLocalAddresses;
    }

    /**
     * {@inheritDoc}
     * @org.apache.xbean.Property nestedType="java.net.SocketAddress"
     */
    @Override
    public final void setDefaultLocalAddresses(List<? extends SocketAddress> localAddresses) {
        if (localAddresses == null) {
            throw new IllegalArgumentException("localAddresses");
        }
        setDefaultLocalAddresses((Iterable<? extends SocketAddress>) localAddresses);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public final void setDefaultLocalAddresses(Iterable<? extends SocketAddress> localAddresses) {
        if (localAddresses == null) {
            throw new IllegalArgumentException("localAddresses");
        }

        synchronized (bindLock) {
            synchronized (boundAddresses) {
                if (!boundAddresses.isEmpty()) {
                    throw new IllegalStateException("localAddress can't be set while the acceptor is bound.");
                }

                Collection<SocketAddress> newLocalAddresses = new ArrayList<>();

                for (SocketAddress a : localAddresses) {
                    checkAddressType(a);
                    newLocalAddresses.add(a);
                }

                if (newLocalAddresses.isEmpty()) {
                    throw new IllegalArgumentException("empty localAddresses");
                }

                this.defaultLocalAddresses.clear();
                this.defaultLocalAddresses.addAll(newLocalAddresses);
            }
        }
    }

    /**
     * {@inheritDoc}
     * @org.apache.xbean.Property nestedType="java.net.SocketAddress"
     */
    @Override
    public final void setDefaultLocalAddresses(SocketAddress firstLocalAddress, SocketAddress... otherLocalAddresses) {
        if (otherLocalAddresses == null) {
            otherLocalAddresses = new SocketAddress[0];
        }

        Collection<SocketAddress> newLocalAddresses = new ArrayList<>(otherLocalAddresses.length + 1);

        newLocalAddresses.add(firstLocalAddress);
        
        for (SocketAddress a : otherLocalAddresses) {
            newLocalAddresses.add(a);
        }

        setDefaultLocalAddresses(newLocalAddresses);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public final boolean isCloseOnDeactivation() {
        return disconnectOnUnbind;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public final void setCloseOnDeactivation(boolean disconnectClientsOnUnbind) {
        this.disconnectOnUnbind = disconnectClientsOnUnbind;
    }

 
  /**
     * A {@Link IoFuture} 
     监听操作结果
     */
    public static class AcceptorOperationFuture extends ServiceOperationFuture {
        private final List<SocketAddress> localAddresses;

        /**
         * Creates a new AcceptorOperationFuture instance
         * 
         * @param localAddresses The list of local addresses to listen to
         */
        public AcceptorOperationFuture(List<? extends SocketAddress> localAddresses) {
            this.localAddresses = new ArrayList<>(localAddresses);
        }
        /**
         * @return The list of local addresses we listen to
         */
        public final List<SocketAddress> getLocalAddresses() {
            return Collections.unmodifiableList(localAddresses);
        }
        /**
         * @see Object#toString()
         */
        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();

            sb.append("Acceptor operation : ");

            if (localAddresses != null) {
                boolean isFirst = true;

                for (SocketAddress address : localAddresses) {
                    if (isFirst) {
                        isFirst = false;
                    } else {
                        sb.append(", ");
                    }

                    sb.append(address);
                }
            }
            return sb.toString();
        }
    }
}


总结;
IoAcceptor与IoService不同的是,添加了监听连接请求和地址绑定功能。抽象Io监听器AbstractIoAcceptor绑定地址首先要检查绑定的socket地址与传输元数据的地址类型是否相同,相同则通过bindInternal完成实际的绑定,然后通知Service监听器,Service已激活fireServiceActivated。解绑地址方法,主要是委托unbind0方法完成实际解绑工作,清空绑定地址集合boundAddresses,触发Service监听器无效事件fireServiceDeactivated。
0
1
分享到:
评论

相关推荐

    Mina+Socket通信

    在Mina与Socket通信的实现中,服务端通常使用Mina来创建一个Acceptor,监听特定端口,等待客户端的连接请求。一旦有连接建立,Mina会自动触发相应的事件处理器,开发者可以在其中处理数据读写。以下是一个基本的...

    mina 中文参考手册 各个接口都做了详尽的描述

    4. 实现 `IoHandler`:创建一个实现了 `IoHandler` 接口的类,定义 `sessionCreated()`, `messageReceived()`, `messageSent()` 等方法,以处理连接建立、数据接收和发送事件。 5. 添加 `IoFilter`:根据需求,创建...

    Apache_Mina_Server中文参考手册.pdf

    3. IoFilter:定义了一组拦截器接口,可以实现诸如日志输出、黑名单过滤以及数据的编码(write方向)和解码(read方向)等功能。其中,数据的编码和解码是使用Mina进行网络通信时重点关注的部分。 4. IoHandler:该...

    Mina 使用DEMO

    - **定义过滤器**:编写自定义的过滤器类,实现IoFilter接口,处理数据的读写和事件处理。 - **配置过滤器链**:在Acceptor中添加预定义的过滤器(如ProtocolCodecFilter)和自定义过滤器,形成处理链路。 - **...

    mina开发实例

    7. **扩展性**:Mina的模块化设计使其易于扩展,可以添加自定义过滤器以实现特定的功能,如日志记录、身份验证、数据压缩等。 由于压缩包中的文件名为"Mina1",我们可以推测它可能是第一个示例或者一个初级教程,...

    mina简单示例

    Mina的核心思想是将网络编程抽象化,使得开发者可以专注于业务逻辑,而不是底层的网络通信细节。 标题中的"mina简单示例"指的是使用Apache Mina框架构建一个简单的客户端和服务端的程序。在Java开发中,Mina提供了...

    Apache mina框架入门教程

    IoService是服务端和客户端的抽象接口。 2. **IoProcessor**:在另一个线程上,IoProcessor负责检查通道上的数据读写,它也有自己的Selector,并负责调用IoFilter链和IoHandler。IoProcessor的职责是执行实际的I/O...

    MINA2与Netty4比较分析

    Mina2使用了一个IoAcceptor线程来监听客户端连接,对于每个监听的端口,它都会创建一个线程。一旦有新的连接,IoAcceptor会创建一个新的IoSession对象,并分配一个IoProcessor线程来处理IO。IoProcessor线程默认数量...

    mina框架demo

    MINA的核心设计理念是提供一个与传输协议无关的抽象层,使得开发者可以专注于业务逻辑,而无需关心底层网络通信的细节。 标题中的"mina框架demo"是指使用MINA框架创建的一个示例项目,通常这个项目会包含一系列的...

    Mina2.0阅读源码笔记(很值得一看)

    - IoService 接口定义了 Mina 中用于处理网络连接的服务,它包括 IoAcceptor 和 IoConnector。 - **IoAcceptor**: 负责监听并接受来自客户端的连接请求。 - **IoConnector**: 用于发起连接到远程服务器的请求。 ...

    Apache Mina Server 2.0 参考手册

    3. **IoFilter**:IoFilter接口定义了一组拦截器,用于实现诸如日志记录、黑名单过滤、数据编码(write方向)和解码(read方向)等功能。编码和解码是使用Mina时的重点,它们决定了数据在网络中的表示形式。 4. **...

    mina文件传输

    在"Mina文件及字符串传输"这个场景中,我们可以理解为利用Mina框架实现了一种服务,允许客户端通过发送字符串请求来获取服务器上的文件。这种功能在分布式系统、文件共享或者远程操作等场景中非常常见。下面我们将...

    Apache Mina Server 2.0 中文参考手册(带目录)

    Mina的架构设计使得它能够将网络通信的底层细节从应用程序中抽象出来,这样开发者只需要关注于编写处理数据和业务逻辑的代码。它将网络通信分解为几个核心组件: 1. IoService:这个接口负责网络连接的建立和维护,...

    mina 中文参考文档

    在开始学习 Mina 之前,需要有一定的 Java IO 和 Java NIO 知识,以及 Java 线程及并发库(java.util.concurrent)的使用经验。 对于 Mina 的 Server 端和 Client 端,Mina 的 API 将实际的网络通信与应用程序逻辑...

    Apache Mina

    4. **Java线程及并发库**: 熟练使用Java中的线程控制和并发工具,如`java.util.concurrent`包下的类和接口。 #### 架构与组件 Mina的核心架构围绕以下几个关键组件展开: 1. **IoService**: 负责套接字的建立,...

    Mina2.0中文参考手册(word版)

    4. **IoHandler**:这个接口定义了业务逻辑的处理,接收和发送数据的代码在这里实现。 下面是一个简单的 TCP 服务器示例: 首先,我们需要创建一个 IoService,即 IoAcceptor,它是服务端和客户端的抽象。对于 TCP...

    NIO_MINA学习例子_源代码

    选择器用于监听多个通道的事件,例如连接、读取和写入,从而实现了单线程处理多个连接的能力,提高了系统资源的利用率。 MINA框架在NIO的基础上,提供了一套完整的API,包括过滤器(Filter)、服务端口(Bind)、会话...

Global site tag (gtag.js) - Google Analytics