ServerSocketChannel channel = ServerSocketChannel.open();
public static ServerSocketChannel open() throws IOException {
return SelectorProvider.provider().openServerSocketChannel();
}
SelectorProviderImpl
public ServerSocketChannel openServerSocketChannel() throws IOException {
return new ServerSocketChannelImpl(this);
}
全局变量
class ServerSocketChannelImpl extends ServerSocketChannel implements SelChImpl {
private final FileDescriptor fd;
private int fdVal;
ServerSocket socket;
}
构造函数
ServerSocketChannelImpl(SelectorProvider var1) throws IOException {
super(var1);
this.fd = Net.serverSocket(true);
this.fdVal = IOUtil.fdVal(this.fd);
this.state = 0;
}
serverSocket
Net.serverSocket
static FileDescriptor serverSocket(boolean var0) {
//创建FileDescriptor 并设置fd
return IOUtil.newFD(socket0(isIPv6Available(), var0, true, fastLoopback));
}
public static FileDescriptor newFD(int var0) {
FileDescriptor var1 = new FileDescriptor();
setfdVal(var1, var0);
return var1;
}
native
返回fd
private static native int socket0(boolean var0, boolean var1, boolean var2, boolean var3);
Java_sun_nio_ch_Net_socket0(JNIEnv *env, jclass cl, jboolean preferIPv6,
jboolean stream, jboolean reuse)
{
int fd;
int type = (stream ? SOCK_STREAM : SOCK_DGRAM); // SOCK_STREAM: Tcp连接,提供序列化的、可靠的、双向连接的字节流。支持带外数据传输 SOCK_DGRAM: 支持UDP连接(无连接状态的消息)
#ifdef AF_INET6
int domain = (ipv6_available() && preferIPv6) ? AF_INET6 : AF_INET;
#else
int domain = AF_INET;
#endif
fd = socket(domain, type, 0); // socket int socket(int domain, int type, int protocol);
if (fd < 0) {
return handleSocketError(env, errno);
}
.................
}
configureBlocking
channel.configureBlocking(false);
# ServerSocketChannelImpl
protected void implConfigureBlocking(boolean var1) throws IOException {
IOUtil.configureBlocking(this.fd, var1);
}
# IOUtil public static native void configureBlocking(FileDescriptor var0, boolean var1) throws IOException;
JNIEXPORT void JNICALL
Java_sun_nio_ch_IOUtil_configureBlocking(JNIEnv *env, jclass clazz,
jobject fdo, jboolean blocking)
{
if (configureBlocking(fdval(env, fdo), blocking) < 0)
JNU_ThrowIOExceptionWithLastError(env, "Configure blocking failed");
}
static int
configureBlocking(int fd, jboolean blocking)
{
// 非阻塞 传入的是blocking=false
int flags = fcntl(fd, F_GETFL); // 获取文件打开方式的标志
int newflags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
return (flags == newflags) ? 0 : fcntl(fd, F_SETFL, newflags);
}



