- 浏览: 984295 次
文章分类
- 全部博客 (428)
- Hadoop (2)
- HBase (1)
- ELK (1)
- ActiveMQ (13)
- Kafka (5)
- Redis (14)
- Dubbo (1)
- Memcached (5)
- Netty (56)
- Mina (34)
- NIO (51)
- JUC (53)
- Spring (13)
- Mybatis (17)
- MySQL (21)
- JDBC (12)
- C3P0 (5)
- Tomcat (13)
- SLF4J-log4j (9)
- P6Spy (4)
- Quartz (12)
- Zabbix (7)
- JAVA (9)
- Linux (15)
- HTML (9)
- Lucene (0)
- JS (2)
- WebService (1)
- Maven (4)
- Oracle&MSSQL (14)
- iText (11)
- Development Tools (8)
- UTILS (4)
- LIFE (8)
最新评论
-
Donald_Draper:
Donald_Draper 写道刘落落cici 写道能给我发一 ...
DatagramChannelImpl 解析三(多播) -
Donald_Draper:
刘落落cici 写道能给我发一份这个类的源码吗Datagram ...
DatagramChannelImpl 解析三(多播) -
lyfyouyun:
请问楼主,执行消息发送的时候,报错:Transport sch ...
ActiveMQ连接工厂、连接详解 -
ezlhq:
关于 PollArrayWrapper 状态含义猜测:参考 S ...
WindowsSelectorImpl解析一(FdMap,PollArrayWrapper) -
flyfeifei66:
打算使用xmemcache作为memcache的客户端,由于x ...
Memcached分布式客户端(Xmemcached)
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:
从IoAcceptor的接口定义可以看,IoAcceptor是将IoService添加了监听连接请求功能。
再来看抽象实现:
来看一下地址绑定操作:
绑定方法有以下几点要看
从上面可以看出,绑定地址首先要检查绑定的socket地址与传输元数据的地址类型是否相同,相同则通过bindInternal完成实际的绑定,然后通知Service监听器,Service已激活fireServiceActivated。
再来看地址解绑:
上面所有的解绑方法实际通过unbind(Iterable<? extends SocketAddress> localAddresses)方法完成:
从解绑地址方法来看,主要是委托unbind0方法完成实际解绑工作,清空绑定地址集合boundAddresses,触发Service监听器无效事件fireServiceDeactivated。
再来看其他方法,下面这些方法就不讲了,都是set和get操作看看就行:
总结;
IoAcceptor与IoService不同的是,添加了监听连接请求和地址绑定功能。抽象Io监听器AbstractIoAcceptor绑定地址首先要检查绑定的socket地址与传输元数据的地址类型是否相同,相同则通过bindInternal完成实际的绑定,然后通知Service监听器,Service已激活fireServiceActivated。解绑地址方法,主要是委托unbind0方法完成实际解绑工作,清空绑定地址集合boundAddresses,触发Service监听器无效事件fireServiceDeactivated。
引言:
上面我们看了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。
发表评论
-
Mina 报文连接器(NioDatagramConnector)
2017-06-14 08:46 1428Mina 抽象Polling连接器(A ... -
Mina 报文监听器NioDatagramAcceptor二(发送会话消息等)
2017-06-13 16:01 1556Mina 报文监听器NioDatagramAcceptor一( ... -
Mina 报文监听器NioDatagramAcceptor一(初始化,Io处理器)
2017-06-13 09:51 2587Mina Io监听器接口定义及抽象实现:http://dona ... -
Mina 报文通信简单示例
2017-06-12 09:01 2599MINA TCP简单通信实例:http://donald-dr ... -
Mina socket连接器(NioSocketConnector)
2017-06-12 08:37 4793Mina 抽象Polling连接器(AbstractPolli ... -
Mina 抽象Polling连接器(AbstractPollingIoConnector)
2017-06-11 21:29 1018Mina 连接器接口定义及抽象实现(IoConnector ) ... -
Mina 连接器接口定义及抽象实现(IoConnector )
2017-06-11 13:46 1840Mina IoService接口定义及抽象实现:http:// ... -
Mina socket监听器(NioSocketAcceptor)
2017-06-09 08:44 3437Mina IoService接口定义及抽象实现:http:// ... -
Mina 抽象polling监听器
2017-06-08 22:32 790Mina Io监听器接口定义及抽象实现:http://dona ... -
Mina IoService接口定义及抽象实现
2017-06-06 23:44 1204Mina IoHandler接口定义:http://donal ... -
Mina Nio会话(Socket,DataGram)
2017-06-06 12:53 1220Mina Socket会话配置:http://donald-d ... -
Mina 抽象Io会话
2017-06-05 22:45 1024Mina Io会话接口定义:http://donald-dra ... -
Mina Io会话接口定义
2017-06-04 23:15 1179Mina Nio处理器:http://donald-drape ... -
Mina Nio处理器
2017-06-04 22:19 751Mina Io处理器抽象实现:http://donald-dr ... -
Mina Io处理器抽象实现
2017-06-03 23:52 1156Mina 过滤链抽象实现:http://donald-drap ... -
Mina IoHandler接口定义
2017-06-01 21:30 1740Mina 过滤链抽象实现:http://donald-drap ... -
MINA 多路复用协议编解码器工厂二(多路复用协议解码器)
2017-06-01 12:52 2287MINA 多路复用协议编解码器工厂一(多路复用协议编码器): ... -
MINA 多路复用协议编解码器工厂一(多路复用协议编码器)
2017-05-31 22:22 1876MINA 多路分离解码器实例:http://donald-dr ... -
Mina 累计协议解码器
2017-05-31 00:09 1236MINA 编解码器实例:http://donald-drape ... -
Mina 协议编解码过滤器三(会话write与消息接收过滤)
2017-05-28 07:22 1759Mina 协议编解码过滤器一(协议编解码工厂、协议编码器): ...
相关推荐
在Mina与Socket通信的实现中,服务端通常使用Mina来创建一个Acceptor,监听特定端口,等待客户端的连接请求。一旦有连接建立,Mina会自动触发相应的事件处理器,开发者可以在其中处理数据读写。以下是一个基本的...
4. 实现 `IoHandler`:创建一个实现了 `IoHandler` 接口的类,定义 `sessionCreated()`, `messageReceived()`, `messageSent()` 等方法,以处理连接建立、数据接收和发送事件。 5. 添加 `IoFilter`:根据需求,创建...
3. IoFilter:定义了一组拦截器接口,可以实现诸如日志输出、黑名单过滤以及数据的编码(write方向)和解码(read方向)等功能。其中,数据的编码和解码是使用Mina进行网络通信时重点关注的部分。 4. IoHandler:该...
- **定义过滤器**:编写自定义的过滤器类,实现IoFilter接口,处理数据的读写和事件处理。 - **配置过滤器链**:在Acceptor中添加预定义的过滤器(如ProtocolCodecFilter)和自定义过滤器,形成处理链路。 - **...
7. **扩展性**:Mina的模块化设计使其易于扩展,可以添加自定义过滤器以实现特定的功能,如日志记录、身份验证、数据压缩等。 由于压缩包中的文件名为"Mina1",我们可以推测它可能是第一个示例或者一个初级教程,...
Mina的核心思想是将网络编程抽象化,使得开发者可以专注于业务逻辑,而不是底层的网络通信细节。 标题中的"mina简单示例"指的是使用Apache Mina框架构建一个简单的客户端和服务端的程序。在Java开发中,Mina提供了...
IoService是服务端和客户端的抽象接口。 2. **IoProcessor**:在另一个线程上,IoProcessor负责检查通道上的数据读写,它也有自己的Selector,并负责调用IoFilter链和IoHandler。IoProcessor的职责是执行实际的I/O...
- 实现此接口可定义如何处理会话创建、关闭、消息接收等事件。 #### 四、Mina中的长连接与短连接 - **长连接**:建立一次连接后保持连接状态,多次通信使用同一连接,适用于频繁交互的场景。 - **短连接**:每次...
MINA的核心设计理念是提供一个与传输协议无关的抽象层,使得开发者可以专注于业务逻辑,而无需关心底层网络通信的细节。 标题中的"mina框架demo"是指使用MINA框架创建的一个示例项目,通常这个项目会包含一系列的...
Mina2使用了一个IoAcceptor线程来监听客户端连接,对于每个监听的端口,它都会创建一个线程。一旦有新的连接,IoAcceptor会创建一个新的IoSession对象,并分配一个IoProcessor线程来处理IO。IoProcessor线程默认数量...
- IoService 接口定义了 Mina 中用于处理网络连接的服务,它包括 IoAcceptor 和 IoConnector。 - **IoAcceptor**: 负责监听并接受来自客户端的连接请求。 - **IoConnector**: 用于发起连接到远程服务器的请求。 ...
3. **IoFilter**:IoFilter接口定义了一组拦截器,用于实现诸如日志记录、黑名单过滤、数据编码(write方向)和解码(read方向)等功能。编码和解码是使用Mina时的重点,它们决定了数据在网络中的表示形式。 4. **...
在"Mina文件及字符串传输"这个场景中,我们可以理解为利用Mina框架实现了一种服务,允许客户端通过发送字符串请求来获取服务器上的文件。这种功能在分布式系统、文件共享或者远程操作等场景中非常常见。下面我们将...
Mina的架构设计使得它能够将网络通信的底层细节从应用程序中抽象出来,这样开发者只需要关注于编写处理数据和业务逻辑的代码。它将网络通信分解为几个核心组件: 1. IoService:这个接口负责网络连接的建立和维护,...
在开始学习 Mina 之前,需要有一定的 Java IO 和 Java NIO 知识,以及 Java 线程及并发库(java.util.concurrent)的使用经验。 对于 Mina 的 Server 端和 Client 端,Mina 的 API 将实际的网络通信与应用程序逻辑...
4. **Java线程及并发库**: 熟练使用Java中的线程控制和并发工具,如`java.util.concurrent`包下的类和接口。 #### 架构与组件 Mina的核心架构围绕以下几个关键组件展开: 1. **IoService**: 负责套接字的建立,...
- **类结构**:`IoFilter`接口同样没有直接实现类,但可以通过继承`AbstractIoFilter`类来实现自己的过滤器。 - **应用**:可以通过`addFilter`方法将自定义的过滤器添加到过滤链中。 **添加过滤器**:在Mina中,...
4. **IoHandler**:这个接口定义了业务逻辑的处理,接收和发送数据的代码在这里实现。 下面是一个简单的 TCP 服务器示例: 首先,我们需要创建一个 IoService,即 IoAcceptor,它是服务端和客户端的抽象。对于 TCP...
选择器用于监听多个通道的事件,例如连接、读取和写入,从而实现了单线程处理多个连接的能力,提高了系统资源的利用率。 MINA框架在NIO的基础上,提供了一套完整的API,包括过滤器(Filter)、服务端口(Bind)、会话...