接着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
{
|
060
|
//
TODO Auto-generated method stub
|
065
|
public void bind(Iterable<? extends SocketAddress>
localAddresses)
|
067
|
//
TODO isDisposing()
|
069
|
if (localAddresses
== null )
{
|
070
|
throw new IllegalArgumentException( "localAddresses" );
|
073
|
List<SocketAddress>
localAddressesCopy = new ArrayList<SocketAddress>();
|
075
|
for (SocketAddress
a : localAddresses) {
|
076
|
//
TODO check address type
|
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) {
|
122
|
//
TODO Auto-generated method stub
|
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);
|
34
|
//
TODO Auto-generated constructor stub
|
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();
|
84
|
//
nHandles+=registerHandles();
|
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);
|
021
|
//
TODO Auto-generated constructor stub
|
025
|
public int getManagedSessionCount()
{
|
026
|
//
TODO Auto-generated method stub
|
031
|
*
这个方法继承自AbstractIoAcceptor
|
033
|
*
The type NioSocketAcceptor must implement the inherited abstract method
|
034
|
*
SocketAcceptor.getLocalAddress() to override
|
035
|
*
AbstractIoAcceptor.getLocalAddress()
|
038
|
public InetSocketAddress
getLocalAddress() {
|
039
|
//
TODO Auto-generated method stub
|
044
|
public void setDefaultLocalAddress(InetSocketAddress
localAddress) {
|
045
|
//
TODO Auto-generated method stub
|
050
|
public boolean isReuseAddress()
{
|
051
|
//
TODO Auto-generated method stub
|
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
{
|
074
|
//
TODO Auto-generated method stub
|
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()
{
|
106
|
//
TODO Auto-generated method stub
|
------------------------------------------------------
到此为止将连接部分都写完了,在连接部分还有些零碎的东西,比如handler、polling,这些都只是稍稍提了一下,具体后面会在介绍其他部分是肯定还会碰上,我还是想把重心放在最主要的部分去写,下一篇应该要写到session了。