上一篇博客ApacheMINA(2)HelloWorld!以一个例子实现了mina客户端和服务端的通讯,现在通过源码来了解建立连接和通讯的过程(基于tcp/ip的实现)。
成都创新互联公司主营双牌网站建设的网络公司,主营网站建设方案,App定制开发,双牌h5微信平台小程序开发搭建,双牌网站营销推广欢迎双牌等地区企业咨询
服务端通过创建一个NioSocketAcceptor来接受请求,客户端通过创建NioSocketConnector来连接服务端并发送请求,从整体的体系结构来看二者的关系。
IoService是对于服务器端接受连接和客户端发起连接两类行为的一个抽象。IoServer用来执行真正的I/O操作,以及管理I/O会话。两个子接口为IoAcceptor和IoConnector。IoAcceptor用来接受连接,与客户端进行通讯。IoConnector用来发起连接,与服务端进行通讯。IoAcceptor和IoConnector都分别有基于TCP/IP协议协议,UDP/IP协议以及虚拟机管道通讯的子接口。HelloWorld例子里面实现的是基于TCP/IP协议的通讯,用了mina默认的实现类NioSocketAcceptor和NioSocketConnector。
首先从服务端的NioSocketAcceptor开始:
1.NioSocketAcceptor的父类为AbstractPollingIoAcceptor,很多实现是在父类中实现的。在构造此类的时候,同时也构造了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,个数为cpu个数+1,为每个IoProcessor初始化一个默认的Excutor
this.executor=Executors.newCachedThreadPool();
初始化cpu+1个放到privatefinalIoProcessor[]pool中,用来处理NioSession,所以S为NioSession
public final class NioProcessor extends AbstractPollingIoProcessor…
2.初始化完SimpleIoProcessorPool,回到AbstractPollingIoAcceptor的构造方法中,调用NioSocketAcceptor中的init()方法打开selector通道,完成NioSocketAcceptor的构造。
3.然后在上一篇HelloWorld的例子中设置了SocketSessionConfig的readBufferSize;
接收数据的过滤器,例子中设置的是TextLineCodecFactory(按照行一行为一个单位读取数据);
实现IoHandlerAdapter来处理客户的请求。
4.最后执行acceptor.bind(newInetSocketAddress(SERVER_PORT)),指定服务提供绑定的端口,同时执行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);
当接收到请求时调用accept()方法法处理接收连接,把SocektChannel绑定到NioSession中
当接收到请求时调用accept()方法法处理接收连接,把SocektChannel绑定到NioSession中 Java代码
绑定完成后唤醒NIO的selector开始接收请求
selector.wakeup();
小结:
通过解析NioSocketAcceptor的构造方法,bind()等代码大概了解了mina服务端初始化相关的一些信息,同时涉及了mina框架相关的IoProcessorIoSessionIoServiceListener等,在下一篇文章中会再做进一步的分析接收到最终的处理请求的过程。