共计 3316 个字符,预计需要花费 9 分钟才能阅读完成。
阅读目录
- 一、客户端开发时序图
- 二、Netty 客户端开发步骤
- 三、Netty 客户端开发示例代码
- 四、参考资料
一、客户端开发时序图
图片来源:Netty 权威指南 (第 2 版)
二、Netty 客户端开发步骤
使用 Netty 进行客户端开发主要有以下几个步骤:
1、用户线程创建 Bootstrap
Bootstrap b = new Bootstrap();
Bootstrap 是 Socket 客户端创建工具类,通过 API 设置创建客户端相关的参数,异步发起客户端连接。
2、创建处理客户端连接、IO 读写的 Reactor 线程组 NioEventLoopGroup
EventLoopGroup group = new NioEventLoopGroup();
3、通过 Bootstrap 的 ChannelFactory 和用户指定的 Channel 类型创建用于客户端连接的 NioSocketChannel
b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true)
此处的 NioSocketChannel 类似于 Java NIO 提供的 SocketChannel。
4、创建默认的 channel Handler pipeline
b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true) | |
.handler(new ChannelInitializer<SocketChannel>() | |
{ | |
@Override | |
public void initChannel(SocketChannel ch) throws Exception | |
{ch.pipeline().addLast(new HelloClientHandler()); | |
} | |
}); |
用于调度和执行网络事件。
5、异步发起 TCP 连接
// 发起异步连接操作 | |
ChannelFuture f = b.connect(host, port).sync(); |
SocketChannel 执行 connect() 操作后有以下三种结果:
- 连接成功,然会 true;
- 暂时没有连接上,服务器端没有返回 ACK 应答,连接结果不确定,返回 false。此种结果下,需要将 NioSocketChannel 中的 selectionKey 设置为 OP_CONNECT,监听连接结果;
- 接连失败,直接抛出 I / O 异常
6、由多路复用器在 I / O 中轮询个 Channel,处理连接结果
7、如果连接成功,设置 Future 结果,发送连接成功事件,触发 ChannelPipeline 执行
8、由 ChannelPipeline 调度执行系统和用户的 ChannelHandler,执行业务逻辑
三、Netty 客户端开发示例代码
需求:客户端端实现,连接服务器端,并向服务器端发送 hello Netty。(注:本代码使用的 netty 是 netty-all-5.0.0.Alpha1-sources.jar 版本)
服务器端代码见 Netty 学习之服务器端创建
客户端代码:
import io.netty.bootstrap.Bootstrap; | |
import io.netty.channel.ChannelFuture; | |
import io.netty.channel.ChannelInitializer; | |
import io.netty.channel.ChannelOption; | |
import io.netty.channel.EventLoopGroup; | |
import io.netty.channel.nio.NioEventLoopGroup; | |
import io.netty.channel.socket.SocketChannel; | |
import io.netty.channel.socket.nio.NioSocketChannel; | |
public class HelloClient | |
{public void connect(int port, String host) throws Exception | |
{// 配置客户端 NIO 线程组 | |
EventLoopGroup group = new NioEventLoopGroup(); | |
try | |
{Bootstrap b = new Bootstrap(); | |
b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true) | |
.handler(new ChannelInitializer<SocketChannel>() | |
{ | |
public void initChannel(SocketChannel ch) throws Exception | |
{ch.pipeline().addLast(new HelloClientHandler()); | |
} | |
}); | |
// 发起异步连接操作 | |
ChannelFuture f = b.connect(host, port).sync(); | |
// 等待客户端链路关闭 | |
f.channel().closeFuture().sync();} finally | |
{group.shutdownGracefully(); | |
} | |
} | |
public static void main(String[] args) throws Exception | |
{int port = 8080; | |
new HelloClient().connect(port, "127.0.0.1"); | |
} | |
} |
import io.netty.buffer.ByteBuf; | |
import io.netty.buffer.Unpooled; | |
import io.netty.channel.ChannelHandlerAdapter; | |
import io.netty.channel.ChannelHandlerContext; | |
public class HelloClientHandler extends ChannelHandlerAdapter | |
{private final ByteBuf message; | |
public HelloClientHandler() | |
{byte[] req="hello Netty".getBytes(); | |
message=Unpooled.buffer(req.length); | |
message.writeBytes(req); | |
} | |
public void channelActive(ChannelHandlerContext ctx) throws Exception | |
{ctx.writeAndFlush(message); | |
} | |
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception | |
{ctx.close(); | |
} | |
} |
程序运行结果:
四、参考资料
1、Netty 权威指南 (李林峰)【Netty 权威指南 PDF 完整版带目录书签 + 源码 下载地址 http://www.linuxidc.com/Linux/2016-07/133575.htm】
运用 Spring 注解实现 Netty 服务器端 UDP 应用程序 http://www.linuxidc.com/Linux/2013-09/89780.htm
Netty 源码学习笔记 http://www.linuxidc.com/Linux/2013-09/89778.htm
Netty 使用实例 http://www.linuxidc.com/Linux/2013-09/89779.htm
Java NIO 框架 –Netty4 的简单示例 http://www.linuxidc.com/Linux/2015-01/111335.htm
Netty 的详细介绍 :请点这里
Netty 的下载地址 :请点这里
本文永久更新链接地址 :http://www.linuxidc.com/Linux/2016-07/133585.htm
