上一篇博客ApacheMINA(2)HelloWorld!以一個例子實現(xiàn)了mina客戶端和服務端的通訊,現(xiàn)在通過源碼來了解建立連接和通訊的過程(基于tcp/ip的實現(xiàn))。
成都創(chuàng)新互聯(lián)公司主營雙牌網(wǎng)站建設的網(wǎng)絡公司,主營網(wǎng)站建設方案,App定制開發(fā),雙牌h5微信平臺小程序開發(fā)搭建,雙牌網(wǎng)站營銷推廣歡迎雙牌等地區(qū)企業(yè)咨詢
服務端通過創(chuàng)建一個NioSocketAcceptor來接受請求,客戶端通過創(chuàng)建NioSocketConnector來連接服務端并發(fā)送請求,從整體的體系結(jié)構來看二者的關系。
IoService是對于服務器端接受連接和客戶端發(fā)起連接兩類行為的一個抽象。IoServer用來執(zhí)行真正的I/O操作,以及管理I/O會話。兩個子接口為IoAcceptor和IoConnector。IoAcceptor用來接受連接,與客戶端進行通訊。IoConnector用來發(fā)起連接,與服務端進行通訊。IoAcceptor和IoConnector都分別有基于TCP/IP協(xié)議協(xié)議,UDP/IP協(xié)議以及虛擬機管道通訊的子接口。HelloWorld例子里面實現(xiàn)的是基于TCP/IP協(xié)議的通訊,用了mina默認的實現(xiàn)類NioSocketAcceptor和NioSocketConnector。
首先從服務端的NioSocketAcceptor開始:
1.NioSocketAcceptor的父類為AbstractPollingIoAcceptor,很多實現(xiàn)是在父類中實現(xiàn)的。在構造此類的時候,同時也構造了NioProcessor類
public NioSocketAcceptor() { super(new DefaultSocketSessionConfig(), NioProcessor.class); ((DefaultSocketSessionConfig) getSessionConfig()).init( } AbstractPollingIoAcceptor
Java代碼
protected AbstractPollingIoAcceptor(IoSessionConfig sessionConfig, Class extends IoProcessor> processorClass) { this(sessionConfig, null, new SimpleIoProcessorPool(processorClass), true); } SimpleIoProcessorPool
Java代碼
private static final int DEFAULT_SIZE = Runtime.getRuntime().availableProcessors() + 1; …… public SimpleIoProcessorPool(Class extends IoProcessor> processorType) { this(processorType, null, DEFAULT_SIZE); }
初始化NioProcessor,個數(shù)為cpu個數(shù)+1,為每個IoProcessor初始化一個默認的Excutor
this.executor=Executors.newCachedThreadPool();
初始化cpu+1個放到privatefinalIoProcessor[]pool中,用來處理NioSession,所以S為NioSession
public final class NioProcessor extends AbstractPollingIoProcessor…
2.初始化完SimpleIoProcessorPool,回到AbstractPollingIoAcceptor的構造方法中,調(diào)用NioSocketAcceptor中的init()方法打開selector通道,完成NioSocketAcceptor的構造。
3.然后在上一篇HelloWorld的例子中設置了SocketSessionConfig的readBufferSize;
接收數(shù)據(jù)的過濾器,例子中設置的是TextLineCodecFactory(按照行一行為一個單位讀取數(shù)據(jù));
實現(xiàn)IoHandlerAdapter來處理客戶的請求。
4.最后執(zhí)行acceptor.bind(newInetSocketAddress(SERVER_PORT)),指定服務提供綁定的端口,同時執(zhí)行AbstractPollingIoAcceptor中的bindInternal方法,
…… ServerSocketChannel channel = ServerSocketChannel.open(); ……
然后配制socket的一些基本屬性,并注冊此事件是可連接的事件
// This is a non blocking socket channel channel.configureBlocking(false); // Configure the server socket, ServerSocket socket = channel.socket(); // Set the reuseAddress flag accordingly with the setting socket.setReuseAddress(isReuseAddress()); // and bind. socket.bind(localAddress, getBacklog()); // Register the channel within the selector for ACCEPT event channel.register(selector, SelectionKey.OP_ACCEPT);
當接收到請求時調(diào)用accept()方法法處理接收連接,把SocektChannel綁定到NioSession中
當接收到請求時調(diào)用accept()方法法處理接收連接,把SocektChannel綁定到NioSession中 Java代碼
綁定完成后喚醒NIO的selector開始接收請求
selector.wakeup();
小結(jié):
通過解析NioSocketAcceptor的構造方法,bind()等代碼大概了解了mina服務端初始化相關的一些信息,同時涉及了mina框架相關的IoProcessorIoSessionIoServiceListener等,在下一篇文章中會再做進一步的分析接收到最終的處理請求的過程。