接着Mina源码阅读笔记(四)—Mina的连接IoConnector1,,我们继续:
AbstractIoAcceptor:
001 | package org.apache.mina.core.rewrite.service; |
003 | import java.io.IOException; |
004 | import java.net.SocketAddress; |
005 | import java.util.ArrayList; |
006 | import java.util.Collections; |
007 | import java.util.HashSet; |
008 | import java.util.List; |
009 | import java.util.Set; |
010 | import java.util.concurrent.Executor; |
012 | public abstract class AbstractIoAcceptor extends AbstractIoService implements |
015 | private final List<SocketAddress> defaultLocalAddresses = new ArrayList<SocketAddress>(); |
017 | private final List<SocketAddress> unmodifiableDeffaultLocalAddresses = Collections |
018 | .unmodifiableList(defaultLocalAddresses); |
020 | private final Set<SocketAddress> boundAddresses = new HashSet<SocketAddress>(); |
022 | private boolean disconnectOnUnbind = true ; |
024 | /** 这里不是很明白,为什么要用protected 而 不是private */ |
025 | protected final Object bindLock = new Object(); |
028 | * 注意这个构造方法是一定要写的,否则编译不通过:抽象类继承时候,构造方法都要写,而且必须包含super |
034 | protected AbstractIoAcceptor(Object param, Executor executor) { |
035 | super (param, executor); |
036 | defaultLocalAddresses.add( null ); |
040 | public SocketAddress getLocalAddress() { |
042 | Set<SocketAddress> localAddresses = getLocalAddresses(); |
043 | if (localAddresses.isEmpty()) { |
046 | return localAddresses.iterator().next(); |
050 | public final Set<SocketAddress> getLocalAddresses() { |
051 | Set<SocketAddress> localAddresses = new HashSet<SocketAddress>(); |
052 | synchronized (boundAddresses) { |
053 | localAddresses.addAll(boundAddresses); |
055 | return localAddresses; |
059 | public void bind(SocketAddress localAddress) throws IOException { |
065 | public void bind(Iterable<? extends SocketAddress> localAddresses) |
069 | if (localAddresses == null ) { |
070 | throw new IllegalArgumentException( "localAddresses" ); |
073 | List<SocketAddress> localAddressesCopy = new ArrayList<SocketAddress>(); |
075 | for (SocketAddress a : localAddresses) { |
077 | localAddressesCopy.add(a); |
080 | if (localAddressesCopy.isEmpty()) { |
081 | throw new IllegalArgumentException( "localAddresses is empty" ); |
084 | boolean active = false ; |
086 | synchronized (bindLock) { |
087 | synchronized (boundAddresses) { |
088 | if (boundAddresses.isEmpty()) { |
093 | /** implement in abstractIoService */ |
094 | if (getHandler() == null ) { |
095 | throw new IllegalArgumentException( "handler is not set" ); |
099 | Set<SocketAddress> addresses = bindInternal(localAddressesCopy); |
101 | synchronized (boundAddresses) { |
102 | boundAddresses.addAll(addresses); |
104 | } catch (IOException e) { |
106 | } catch (RuntimeException e) { |
108 | } catch (Throwable e) { |
109 | throw new RuntimeException( "Filed ti bind" ); |
117 | protected abstract Set<SocketAddress> bindInternal( |
118 | List<? extends SocketAddress> localAddress) throws Exception; |
121 | public void unbind(SocketAddress localAddress) { |
polling:
01 | package org.apache.mina.core.rewrite.polling; |
03 | import java.net.SocketAddress; |
04 | import java.nio.channels.ServerSocketChannel; |
05 | import java.util.List; |
07 | import java.util.concurrent.Executor; |
08 | import java.util.concurrent.Semaphore; |
09 | import java.util.concurrent.atomic.AtomicReference; |
11 | import org.apache.mina.core.rewrite.service.AbstractIoAcceptor; |
13 | public abstract class AbstractPollingIoAcceptor extends AbstractIoAcceptor { |
15 | private final Semaphore lock = new Semaphore( 1 ); |
17 | private volatile boolean selectable; |
19 | private AtomicReference<Acceptor> acceptorRef = new AtomicReference<Acceptor>(); |
22 | * define the num of sockets that can wait to be accepted. |
24 | protected int backlog = 50 ; |
32 | protected AbstractPollingIoAcceptor(Object param, Executor executor) { |
33 | super (param, executor); |
38 | * init the polling system. will be called at construction time |
42 | protected abstract void init() throws Exception; |
44 | protected abstract void destory() throws Exception; |
46 | protected abstract int select() throws Exception; |
48 | protected abstract ServerSocketChannel open(SocketAddress localAddress) throws Exception; |
51 | protected Set<SocketAddress> bindInternal( |
52 | List<? extends SocketAddress> localAddress) throws Exception { |
65 | * this class is called by startupAcceptor() method it's a thread accepting |
66 | * incoming connections from client |
71 | private class Acceptor implements Runnable { |
74 | assert (acceptorRef.get() == this ); |
82 | int selected = select(); |
87 | acceptorRef.set( null ); |
90 | } catch (Exception e) { |
好了最后看NioSoeketAcceptor:
001 | package org.apache.mina.rewrite.transport.socket.nio; |
003 | import java.net.InetSocketAddress; |
004 | import java.net.ServerSocket; |
005 | import java.net.SocketAddress; |
006 | import java.nio.channels.SelectionKey; |
007 | import java.nio.channels.Selector; |
008 | import java.nio.channels.ServerSocketChannel; |
009 | import java.util.concurrent.Executor; |
011 | import org.apache.mina.core.rewrite.polling.AbstractPollingIoAcceptor; |
012 | import org.apache.mina.rewrite.transport.socket.SocketAcceptor; |
014 | public final class NioSocketAcceptor extends AbstractPollingIoAcceptor |
015 | implements SocketAcceptor { |
017 | private volatile Selector selector; |
019 | protected NioSocketAcceptor(Object param, Executor executor) { |
020 | super (param, executor); |
025 | public int getManagedSessionCount() { |
031 | * 这个方法继承自AbstractIoAcceptor |
033 | * The type NioSocketAcceptor must implement the inherited abstract method |
034 | * SocketAcceptor.getLocalAddress() to override |
035 | * AbstractIoAcceptor.getLocalAddress() |
038 | public InetSocketAddress getLocalAddress() { |
044 | public void setDefaultLocalAddress(InetSocketAddress localAddress) { |
050 | public boolean isReuseAddress() { |
056 | protected void init() throws Exception { |
057 | selector = Selector.open(); |
061 | protected void destory() throws Exception { |
062 | if (selector != null ) { |
068 | protected int select() throws Exception { |
069 | return selector.select(); |
073 | protected void dispose0() throws Exception { |
078 | protected ServerSocketChannel open(SocketAddress localAddress) |
080 | ServerSocketChannel channel =ServerSocketChannel.open(); |
082 | boolean success= false ; |
085 | channel.configureBlocking( false ); |
087 | ServerSocket socket=channel.socket(); |
089 | socket.setReuseAddress(isReuseAddress()); |
091 | socket.bind(localAddress); |
093 | channel.register(selector, SelectionKey.OP_ACCEPT); |
105 | public boolean isActive() { |
------------------------------------------------------
到此为止将连接部分都写完了,在连接部分还有些零碎的东西,比如handler、polling,这些都只是稍稍提了一下,具体后面会在介绍其他部分是肯定还会碰上,我还是想把重心放在最主要的部分去写,下一篇应该要写到session了。