前面看了服务端绑定和读写的流程,再来看客户端,瞬间感觉简单多了~
客户端和服务端相比,区别主要在NioClientBoss上,worker是一样的。来看一个简单的客户端:
ClientBootstrap bootstrap = new ClientBootstrap(
new NioClientSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool()));
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
@Override
public ChannelPipeline getPipeline() throws Exception {
return Channels.pipeline(new PrintHandler());
}
});
ChannelFuture future = bootstrap.connect(new InetSocketAddress(1210));
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future)
throws Exception {
String message = "hello pony";
ChannelBuffer buffer = ChannelBuffers.buffer(message.length());
buffer.writeBytes(message.getBytes());
future.getChannel().write(buffer);
}
});
1. 首先是构造NioClientSocketChannelFactory
主要就是把boss和worker线程池传进去用于构造Channel。
① new NioWorkerPool
与服务端相同,启动了一组IOT,并构造对应的selector。
② new NioClientBossPool
与服务端也是一样的,启动BT和selector,只不过另外构造了一个HashedWheelTimer,经典的时间轮算法,经常用于处理连接超时的情况,时间复杂度很低,具体我也不大明白,求恶补啊。。。
2. 调用connect
① new Channel
前面构造了factory,现在来构造channel:
NioClientSocketChannel(
ChannelFactory factory, ChannelPipeline pipeline,
ChannelSink sink, NioWorker worker) {
super(null, factory, pipeline, sink, newSocket(), worker);
fireChannelOpen(this);
}
将factory,pipeline,sink,socket和worker等传入构造器,构造Netty层的“逻辑”channel对象。其中在执行父类构造器方法AbstractChannel时,会随机生成一个id,并注册当前channel到allChannels上(id唯一,若已占用则递增直到找到可用的为止)。
② channel构造好后,fireChannelOpen(上行事件),经过层层handler处理后,到达sink,默认处理为丢弃事件。
③ 调Channels.connect
这是Netty层发起的下行事件,也是经过层层handler,最终到NioClientSocketPipelineSink.eventSunk(不同的ChannelStateEvent处理不同)。
在connect方法中:
if (channel.channel.connect(remoteAddress)) {
channel.worker.register(channel, cf);
} else {
channel.getCloseFuture().addListener(new ChannelFutureListener() {
public void operationComplete(ChannelFuture f)
throws Exception {
if (!cf.isDone()) {
cf.setFailure(new ClosedChannelException());
}
}
});
cf.addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
channel.connectFuture = cf;
nextBoss().register(channel, cf);
}
首先尝试在发起connect的线程中(UT)connect一次,如果成功则获取对应worker并注册INTEREST到worker.selector上;否则投递一个OP_CONNECT给BT(非阻塞模式下的connect会异步、并发的建立连接,当检查到连接已建立成功时,必须通过调用finishConnect来完成建立连接动作,NioClientBoss.process中调用了finishConnect)。
④ 投递OP_CONNECT后,BT在process时先processSelectedKeys,轮询key,若isConnected(即OP_CONNECT被选中),则finishConnect并注册INTEREST到worker.selector(与首次尝试connect成功后的操作相同)。然后BT processConnectTimeout,将selector中的每个channel(注册selector时以attachment形式放入的)取出进行超时判断。
总的来说客户端连接流程很简单,主要是finishConnect和连接超时的处理。HashedWheelTimer等哪天看了再发吧。。。
本人辛苦分析、码字,请尊重他人劳动成果,转载不注明出处的诅咒你当一辈子一线搬砖工,嘿嘿~
欢迎讨论、指正~~
下篇预告:暂时还没想好
相关推荐
源码分析时,首先需要关注的是 Netty 的启动流程,这通常从 `ServerBootstrap` 类开始。ServerBootstrap 配置了 EventLoopGroup(包含多个 EventLoop)和 Channel 实例,如 NioServerSocketChannel。然后通过绑定...
#### 五、Netty源码分析实战案例 1. **ChannelHandlerContext与ChannelHandlerAdaptor详解**: - 分析`ChannelHandlerContext`的生命周期及其与`ChannelHandler`之间的交互方式。 - 深入理解`...
Netty 是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的...通过研读Netty源码,不仅可以提升对网络编程的理解,还能掌握一种高性能的框架设计思想,对于提升个人技术水平和解决实际问题大有裨益。
Netty 的源码分析主要包括以下几个方面: 1. **I/O 模型**:理解 Netty 如何利用 NIO 实现非阻塞 I/O,包括 Channel、Selector 和 Socket 的工作原理。 2. **Pipeline 实现**:分析 Handler 的添加、移除和调用链的...
通过对Netty源码的深入分析,我们不仅能够了解到其内部工作原理,还能学习到许多优秀的设计思想和技术实践,这对于提高个人的技术水平和解决实际问题有着非常重要的意义。希望本文能够帮助读者更好地理解和掌握Netty...
### Netty源码分析 #### 1. Netty简介 Netty是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器与客户端。其核心设计思想是简化网络编程的复杂性,并提供高度可定制化的API,...
本教程的3-4集是Netty快速入门系列的一部分,旨在帮助初学者快速理解并掌握Netty的基本概念和核心特性。 在"第三课netty客户端"中,我们将学习如何使用Netty构建网络客户端。Netty提供了高度定制化的客户端...
在本文中,我们将深入分析 Netty 4.1 源码中的 EchoServer 示例,以理解其核心组件和工作原理。 首先,我们关注 EchoServer 服务端的初始化,这涉及到两个关键组件:`bossGroup` 和 `workerGroup`。它们都是 `...
这些示例通常会展示如何创建一个基本的Netty服务器来监听和响应客户端连接,以及如何构建一个客户端来发起连接并发送数据。通过分析这些示例,开发者可以学习到如何配置和启动Netty的Bootstrap,定义ChannelHandler...
此外,源码分析有助于我们了解 Netty 如何处理网络事件、协议解析、线程调度等核心问题,对于提高开发水平和解决实际问题大有裨益。 书中可能涵盖了以下主题: - Netty 的设计理念和架构 - 异步事件驱动模型的实现...
总的来说,Netty源码剖析与实战视频教程将引导你深入了解Netty的架构和工作流程,提升你的网络编程能力。通过学习,你不仅可以理解Netty如何实现高效的网络通信,还能学会如何利用它的强大功能来构建高性能的网络...
《Netty源码深入剖析》一书旨在帮助读者深入了解Netty框架的工作原理和技术细节,从基础知识入手,逐步过渡到高级优化技巧,使开发者能够更好地掌握并应用Netty于实际项目中。 ### 一、Netty简介与核心特性 Netty...
以上内容便是Netty源码阅读笔记中提到的主要知识点。这些知识点构成了Netty框架的核心,涵盖了从数据容器到事件处理,再到粘包半包问题处理的完整流程。了解和掌握这些知识点对于深入使用Netty进行网络编程具有重要...
JavaVIP课程深入分析了Netty源码,由Tom老师主讲,主要针对咕泡学院的高级Java学员。本文档详细探讨了Netty框架的核心组件及其使用,特别关注了BootStrap类在客户端和服务器端的角色。 BootStrap是Netty提供的一种...
深入源码分析,我们可以看到Netty如何优雅地处理了线程安全、内存池管理、心跳机制、解码编码、零拷贝等高级特性。例如,Netty通过内部的DirectBufferPool和HeapBufferPool实现了内存池,减少了内存分配和释放的开销...
- **源码分析篇**: 分析Netty关键组件的内部实现,如BossGroup、WorkerGroup的工作流程,以及EventLoop的调度机制。 - **实战篇**: 提供实际项目中使用Netty的案例,比如构建WebSocket服务器、HTTP服务器等。 - *...