【Netty源码分析】客户端connect服务端过程
2016-11-23 10:36
861 查看
上一篇博客【Netty源码分析】Netty服务端bind端口过程 我们介绍了服务端绑定端口的过程,这一篇博客我们介绍一下客户端连接服务端的过程。
ChannelFuture future = boostrap.connect("127.0.0.1", 8080).sync(); 调用BootStrap的connect函数public ChannelFuture connect(String inetHost, int inetPort) {
return connect(InetSocketAddress.createUnresolved(inetHost, inetPort));
}
........
return doResolveAndConnect0(channel, remoteAddress, localAddress, channel.newPromise());
........
}
private static void doConnect(
final SocketAddress remoteAddress, final SocketAddress localAddress, final ChannelPromise connectPromise) {
// This method is invoked before channelRegistered() is triggered. Give user handlers a chance to set up
// the pipeline in its channelRegistered() implementation.
final Channel channel = connectPromise.channel();
channel.eventLoop().execute(new Runnable() {
@Override
public void run() {
if (localAddress == null) {
channel.connect(remoteAddress, connectPromise);
} else {
channel.connect(remoteAddress, localAddress, connectPromise);
}
connectPromise.addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
}
});
}
AbstractChannel的connect函数
@Override
public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) {
return pipeline.connect(remoteAddress, localAddress, promise);
}
if (invokeHandler()) {
try {
((ChannelOutboundHandler) handler()).connect(this, remoteAddress, localAddress, promise);
} catch (Throwable t) {
notifyOutboundHandlerException(t, promise);
}
} else {
connect(remoteAddress, localAddress, promise);
}
}HeadContext的connect函数@Override
public void connect(
ChannelHandlerContext ctx,
SocketAddress remoteAddress, SocketAddress localAddress,
ChannelPromise promise) throws Exception {
unsafe.connect(remoteAddress, localAddress, promise);
}AbstractUnsafe函数的connect函数@Override
public final void connect(
final SocketAddress remoteAddress, final SocketAddress localAddress, final ChannelPromise promise) {
.......
if (doConnect(remoteAddress, localAddress)) {
fulfillConnectPromise(promise, wasActive);
}
.......
}调用NioSocketChannle的doConnect函数 @Override
protected boolean doConnect(SocketAddress remoteAddress, SocketAddress localAddress) throws Exception {
if (localAddress != null) {
doBind0(localAddress);
}
boolean success = false;
try {
boolean connected = javaChannel().connect(remoteAddress);
if (!connected) {
selectionKey().interestOps(SelectionKey.OP_CONNECT);
}
success = true;
return connected;
} finally {
if (!success) {
doClose();
}
}
}或许执行doBind0函数
private void doBind0(SocketAddress localAddress) throws Exception {
if (PlatformDependent.javaVersion() >= 7) {
javaChannel().bind(localAddress);
} else {
javaChannel().socket().bind(localAddress);
}
}javaChannle()函数获得的就是SocketChannle对象,这样就完成了客户端连接服务端的操作。
ChannelFuture future = boostrap.connect("127.0.0.1", 8080).sync(); 调用BootStrap的connect函数public ChannelFuture connect(String inetHost, int inetPort) {
return connect(InetSocketAddress.createUnresolved(inetHost, inetPort));
}
public ChannelFuture connect(SocketAddress remoteAddress) { if (remoteAddress == null) { throw new NullPointerException("remoteAddress"); } validate(); return doResolveAndConnect(remoteAddress, config.localAddress()); }调用doResolveAndConnect函数 private ChannelFuture doResolveAndConnect(final SocketAddress remoteAddress, final SocketAddress localAddress) {
........
return doResolveAndConnect0(channel, remoteAddress, localAddress, channel.newPromise());
........
}
private ChannelFuture doResolveAndConnect0(final Channel channel, SocketAddress remoteAddress, final SocketAddress localAddress, final ChannelPromise promise) ........ doConnect(remoteAddress, localAddress, promise); ........ }调用doConnect函数时会同时开启一个线程,用来处理客户端的操作。
private static void doConnect(
final SocketAddress remoteAddress, final SocketAddress localAddress, final ChannelPromise connectPromise) {
// This method is invoked before channelRegistered() is triggered. Give user handlers a chance to set up
// the pipeline in its channelRegistered() implementation.
final Channel channel = connectPromise.channel();
channel.eventLoop().execute(new Runnable() {
@Override
public void run() {
if (localAddress == null) {
channel.connect(remoteAddress, connectPromise);
} else {
channel.connect(remoteAddress, localAddress, connectPromise);
}
connectPromise.addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
}
});
}
AbstractChannel的connect函数
@Override
public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) {
return pipeline.connect(remoteAddress, localAddress, promise);
}
@Override public final ChannelFuture connect( SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) { return tail.connect(remoteAddress, localAddress, promise); }private void invokeConnect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) {
if (invokeHandler()) {
try {
((ChannelOutboundHandler) handler()).connect(this, remoteAddress, localAddress, promise);
} catch (Throwable t) {
notifyOutboundHandlerException(t, promise);
}
} else {
connect(remoteAddress, localAddress, promise);
}
}HeadContext的connect函数@Override
public void connect(
ChannelHandlerContext ctx,
SocketAddress remoteAddress, SocketAddress localAddress,
ChannelPromise promise) throws Exception {
unsafe.connect(remoteAddress, localAddress, promise);
}AbstractUnsafe函数的connect函数@Override
public final void connect(
final SocketAddress remoteAddress, final SocketAddress localAddress, final ChannelPromise promise) {
.......
if (doConnect(remoteAddress, localAddress)) {
fulfillConnectPromise(promise, wasActive);
}
.......
}调用NioSocketChannle的doConnect函数 @Override
protected boolean doConnect(SocketAddress remoteAddress, SocketAddress localAddress) throws Exception {
if (localAddress != null) {
doBind0(localAddress);
}
boolean success = false;
try {
boolean connected = javaChannel().connect(remoteAddress);
if (!connected) {
selectionKey().interestOps(SelectionKey.OP_CONNECT);
}
success = true;
return connected;
} finally {
if (!success) {
doClose();
}
}
}或许执行doBind0函数
private void doBind0(SocketAddress localAddress) throws Exception {
if (PlatformDependent.javaVersion() >= 7) {
javaChannel().bind(localAddress);
} else {
javaChannel().socket().bind(localAddress);
}
}javaChannle()函数获得的就是SocketChannle对象,这样就完成了客户端连接服务端的操作。
相关文章推荐
- 【Netty源码分析】客户端connect服务端过程
- 【Netty源码分析】客户端connect服务端过程
- Netty 4.0源码分析1:服务端启动过程中的Channel与EventLoopGroup的注册
- netty 5 alph1源码分析(服务端创建过程)
- Netty源码分析之客户端启动过程
- Netty源码分析:服务端启动全过程(篇幅很长)
- Netty5源码分析--3.客户端与服务端交互过程详解
- dubbo源码分析-客户端DubboInvoker调用服务端体会Netty的非阻塞IO使用
- 【Netty源码分析】Netty服务端bind端口过程
- Netty源码分析之服务端启动过程
- mina2.0 源码分析--- 基于nio的服务端socket监听过程
- Fresco 源码分析(二) Fresco客户端与服务端交互(2) Fresco.initializeDrawee()分析 续
- 【Zookeeper源码二】Zookeeper 客户端创建连接过程分析
- zookeeper源码分析之一服务端启动过程
- SpringMVC源码总结(四)由StringHttpMessageConverter引出的客户端服务器端之间的乱码过程分析
- Fresco 源码分析(二) Fresco客户端与服务端交互(3) 前后台打通
- Netty5源码分析--2.客户端启动过程
- 通过一个简单的例子看服务端的启动过程以及客户端与服务端的连接过程(Netty 4.0.18)