《Java 源码分析》:Java NIO 之 ServerSocketChannel
在上两篇博文中,主要从源码的角度粗略的介绍了Selector.open()和selector.select()方法的内部实现。
由于Selector和ServerSocketChannel、SocketChannel配合使用,因此,有必要了解ServerSocketChannel、SocketChannel的内部实现。本篇博文主要来看下ServerSocketChannel。
关于ServerSocketChannel类,我们主要从以下几个方法为切入点进行跟踪了解。
1、ServerSocketChannel ssc = ServerSocketChannel.open();
2、ssc.register(selector,SelectionKey.interestOps);
下面就从第一点开始
1、解析ServerSocketChannel.open()
ServerSocketChannel类中open()方法的源码如下:
public static ServerSocketChannel open() throws IOException {
return SelectorProvider.provider().openServerSocketChannel();
}
函数功能:打开一个ServerSocketChannel;
来分析ServerSocketChannel.open()方法中唯一的一行代码:SelectorProvider.provider().openServerSocketChannel()
在关于Selector中的这篇博文中我们分析过,SelectorProvider.provider()方法在windows平台下返回的是SelectorProvider 的实现类 WindowsSelectorProvider类的实例。
其中WindowsSelectorProvider、SelectorProvider类他们的之间的继承关系如下:
- WindowsSelectorProvider类的直接父类为:SelectorProviderImpl
- SelectorProviderImpl 的直接父类是 SelectorProvider。
因此SelectorProvider.provider().openServerSocketChannel()就是等效于:windowsSelectorProvider.openServerSocketChannel();而 openServerSocketChannel()方法并不是在 WindowsSelectorProvider 类中实现的,而是在其直接父类中SelectorProviderImpl类中实现的。
--------- SelectorProviderImpl --------------
public ServerSocketChannel openServerSocketChannel() throws IOException {
return new ServerSocketChannelImpl(this);
}
看见这些代码是不是和Selector.open()基本类似。即ServerSocketChannel.open()方法实际上是产生了一个子类ServerSocketChannelImpl的对象实例。
既然如下,接下来来看下这个子类ServerSocketChannelImpl。
--------- ServerSocketChannelImpl.java --------
class ServerSocketChannelImpl
extends ServerSocketChannel
implements SelChImpl
构造函数
// Our file descriptor
private final FileDescriptor fd;
// fd value needed for dev/poll. This value will remain valid
// even after the value in the file descriptor object has been set to -1
private int fdVal;
ServerSocketChannelImpl(