服务端的socket在哪里初始化的?
在哪里accpet连接的?
Netty服务端启动
创建服务端Channel
初始化服务端Channel
注册selector
端口绑定
1.创建服务端Channel
//创建服务端Channel的入口
ChannelFuture f = b.bind(8888).sync();
//进入bind
public ChannelFuture bind(int inetPort) {
return this.bind(new InetSocketAddress(inetPort));
}
//进入bind
public ChannelFuture bind(SocketAddress localAddress) {
this.validate();
if (localAddress == null) {
throw new NullPointerException("localAddress");
} else {
return this.doBind(localAddress);
}
}
//进入doBind()
private ChannelFuture doBind(final SocketAddress localAddress) {
final ChannelFuture regFuture = this.initAndRegister();
final Channel channel = regFuture.channel();
if (regFuture.cause() != null) {
return regFuture;
} else if (regFuture.isDone()) {
ChannelPromise promise = channel.newPromise();
doBind0(regFuture, channel, localAddress, promise);
return promise;
} else {
final AbstractBootstrap.PendingRegistrationPromise promise = new AbstractBootstrap.PendingRegistrationPromise(channel);
regFuture.addListener(new ChannelFutureListener() {
public void operationComplete(ChannelFuture future) throws Exception {
Throwable cause = future.cause();
if (cause != null) {
promise.setFailure(cause);
} else {
promise.registered();
AbstractBootstrap.doBind0(regFuture, channel, localAddress, promise);
}
}
});
return promise;
}
}
//在此initAndRegidter()种进行创建
final ChannelFuture initAndRegister() {
Channel channel = null;
try {
channel = this.channelFactory.newChannel();
this.init(channel);
} catch (Throwable var3) {
if (channel != null) {
channel.unsafe().closeForcibly();
}
return (new DefaultChannelPromise(channel, GlobalEventExecutor.INSTANCE)).setFailure(var3);
}
ChannelFuture regFuture = this.config().group().register(channel);
if (regFuture.cause() != null) {
if (channel.isRegistered()) {
channel.close();
} else {
channel.unsafe().closeForcibly();
}
}
return regFuture;
}
最后发现是在channelFactory通过反射创建的。
下面是对反射创建服务端Channel的解析
1.newSocket():通过jdk来创建底层jdk channel
2.NioServerSocketChannelConfig():tcp参数配置类
3.AbstractNioChannel()
configureBlocking(false):阻塞模式
AbstractChannel():创建id,unsafe,pipeline
//1.newSocket()方法
public NioServerSocketChannel() {
this(newSocket(DEFAULT_SELECTOR_PROVIDER));
}
//这个openServerSocketChannel()是调用java底层包创建一个Socket
private static java.nio.channels.ServerSocketChannel newSocket(SelectorProvider provider) {
try {
return provider.openServerSocketChannel();
} catch (IOException var2) {
throw new ChannelException("Failed to open a server socket.", var2);
}
}
//2.NioServerSocketChannelConfig()
public NioServerSocketChannel(java.nio.channels.ServerSocketChannel channel) {
super((Channel)null, channel, 16);
this.config = new NioServerSocketChannel.NioServerSocketChannelConfig(this, this.javaChannel().socket());
}
//3.AbstractNioChannel()设置阻塞模式
protected AbstractNioChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
super(parent);
this.ch = ch;
this.readInterestOp = readInterestOp;
try {
ch.configureBlocking(false);
} catch (IOException var7) {
try {
ch.close();
} catch (IOException var6) {
if (logger.isWarnEnabled()) {
logger.warn("Failed to close a partially initialized socket.", var6);
}
}
throw new ChannelException("Failed to enter non-blocking mode.", var7);
}
}
// AbstractChannel():创建id,unsafe,pipeline
protected AbstractChannel(Channel parent) {
this.parent = parent;
this.id = this.newId();
//对于tcp底层的操作
this.unsafe = this.newUnsafe();
this.pipeline = this.newChannelPipeline();
}
2.init():初始化服务端Channel
init():初始化入口
1.set ChannelOptions,ChannelAttrs
2.set ChildOptions,ChildAttrs
3.config handler :配置服务端pipeline
4.add ServerBootstrapAcceptor:添加连接器
//1.用户自定义的属性放在Channel中
void init(Channel channel) throws Exception {
Map, Object> options = this.options0();
synchronized(options) {
channel.config().setOptions(options);
}
Map, Object> attrs = this.attrs0();
synchronized(attrs) {
Iterator i$ = attrs.entrySet().iterator();
while(true) {
if (!i$.hasNext()) {
break;
}
Entry, Object> e = (Entry)i$.next();
AttributeKey
保存用户自定义的属性,然后通过这些属性创建一个连接接入器,连接接入器每次accpet一个连接后,都会对其连接做一个配置。
3.注册到selector上面
1.AbstractChannel.register(channel):入口
this.eventLoop = eventLoop:绑定线程
resgiter0():实际注册
doRegister():调用jdk底层注册
invokeHandlerAddedIfNeeded()
fireChannelRegistered():传播事件
//1.AbstractChannel.register(channel):入口
public final void register(EventLoop eventLoop, final ChannelPromise promise) {
if (eventLoop == null) {
throw new NullPointerException("eventLoop");
} else if (AbstractChannel.this.isRegistered()) {
promise.setFailure(new IllegalStateException("registered to an event loop already"));
} else if (!AbstractChannel.this.isCompatible(eventLoop)) {
promise.setFailure(new IllegalStateException("incompatible event loop type: " + eventLoop.getClass().getName()));
} else {
AbstractChannel.this.eventLoop = eventLoop;
if (eventLoop.inEventLoop()) {
this.register0(promise);
} else {
try {
eventLoop.execute(new Runnable() {
public void run() {
AbstractUnsafe.this.register0(promise);
}
});
} catch (Throwable var4) {
AbstractChannel.logger.warn("Force-closing a channel whose registration task was not accepted by an event loop: {}", AbstractChannel.this, var4);
this.closeForcibly();
AbstractChannel.this.closeFuture.setClosed();
this.safeSetFailure(promise, var4);
}
}
}
}
//2.register()方法
private void register0(ChannelPromise promise) {
try {
if (!promise.setUncancellable() || !this.ensureOpen(promise)) {
return;
}
boolean firstRegistration = this.neverRegistered;
AbstractChannel.this.doRegister();
this.neverRegistered = false;
AbstractChannel.this.registered = true;
AbstractChannel.this.pipeline.invokeHandlerAddedIfNeeded();
this.safeSetSuccess(promise);
AbstractChannel.this.pipeline.fireChannelRegistered();
if (AbstractChannel.this.isActive()) {
if (firstRegistration) {
AbstractChannel.this.pipeline.fireChannelActive();
} else if (AbstractChannel.this.config().isAutoRead()) {
this.beginRead();
}
}
} catch (Throwable var3) {
this.closeForcibly();
AbstractChannel.this.closeFuture.setClosed();
this.safeSetFailure(promise, var3);
}
}
//doRegister()
protected void doRegister() throws Exception {
boolean selected = false;
while(true) {
try {
this.selectionKey = this.javaChannel().register(this.eventLoop().selector, 0, this);
return;
} catch (CancelledKeyException var3) {
if (selected) {
throw var3;
}
this.eventLoop().selectNow();
selected = true;
}
}
}
//
4.端口绑定
AbstractUnsafe.bind():入口
doBind()
javaChannel().bind():jdk底层绑定
pipeline.fireChannelActive():传播事件
HeadContext.readIfIsAutoRead()
private static void doBind0(final ChannelFuture regFuture, final Channel channel, final SocketAddress localAddress, final ChannelPromise promise) {
channel.eventLoop().execute(new Runnable() {
public void run() {
if (regFuture.isSuccess()) {
channel.bind(localAddress, promise).addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
} else {
promise.setFailure(regFuture.cause());
}
}
});
}