提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
- 一、Netty是什么?
- 二、使用步骤
- 1.引入库
- 2.使用案例
- 总结
前言
提示:学习之前,最好能够去官网看看,去github看看使用案例:
Netty例子:https://github.com/netty/netty/tree/4.1/example/src/main/java/io/netty/example
提示:开始第一次学习
一、Netty是什么?
官方定义:Netty 是一个 NIO 客户端服务器框架,可以快速轻松地开发协议服务器和客户端等网络应用程序;
个人理解:Netty是一个编写服务器的框架,主要作用是定义协议,通俗理解就是定义一个网络中的实体;
二、使用步骤
1.引入库
maven中引入依赖(示例):
<!--netty依赖-->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.39.Final</version>
</dependency>
2.使用案例
服务器端代码如下(示例):
public class Server {
private static final Logger log = LoggerFactory.getLogger(Server.class);
private int port;
public Server(int port) {
this.port = port;
}
public void run() throws Exception {
NioEventLoopGroup boosGroup = new NioEventLoopGroup();// 1.NioEventLoopGroup是一个处理 I/O 操作的多线程事件循环。NettyEventLoopGroup为不同类型的传输提供了不同的实现
NioEventLoopGroup workerGroup = new NioEventLoopGroup(2);
try {
ServerBootstrap sb = new ServerBootstrap();// 2.ServerBootstrap是一个设置服务器的辅助类。使用来设置服务器Channel
sb.group(boosGroup,workerGroup)
.channel(NioServerSocketChannel.class) //3.在这里,我们指定使用NioServerSocketChannel用于实例化新Channel接受传入连接的类。
.childHandler(new ChannelInitializer<SocketChannel>() {// 4、此处指定的处理程序将始终由新接受的Channel. 是一个特殊的ChannelInitializer处理程序,旨在帮助用户配置一个新的Channel.
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new TimeServerHandler());
}
})
.option(ChannelOption.SO_BACKLOG,128) // 5、您还可以设置特定于Channel实现的参数。我们正在编写一个 TCP/IP 服务器,因此我们可以设置套接字选项,例如tcpNoDelay和keepAlive。
.childOption(ChannelOption.SO_KEEPALIVE,true); // 6、你注意到了option()吗childOption()?option()适用于NioServerSocketChannel接受传入连接的。childOption()是为Channelparent 接受的 s ServerChannel,NioSocketChannel在这种情况下。
ChannelFuture future = sb.bind(port).sync();
//等待服务器套接字关闭。
//关闭您的服务器
future.channel().closeFuture().sync();
}finally {
workerGroup.shutdownGracefully();
boosGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
int port = 8999;// 端口号
new Server(port).run(); // 实例化启动
}
}
客户端代码如下(示例):
public class Client {
public static void main(String[] args) throws InterruptedException {
// String host = args[0];
// int port = Integer.parseInt(args[1]);
String host = "127.0.0.1";
int port = 8999;
NioEventLoopGroup workersGroup = new NioEventLoopGroup();
try {
Bootstrap bs = new Bootstrap();// 1.BootstrapServerBootstrap除了它用于非服务器通道(例如客户端或无连接通道)之外,它类似于。
bs.group(workersGroup);//2.如果您只指定一个EventLoopGroup,它将同时用作老板组和工人组。但是 boss worker 不用于客户端。
bs.channel(NioSocketChannel.class);// 3.不是NioServerSocketChannel,NioSocketChannel被用来创建客户端Channel.
bs.option(ChannelOption.SO_KEEPALIVE,true);
bs.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new TimeDecoder(),new TimeClientHandler());// 添加通道中的处理器,主要业务写在里面
}
});
// 开启客户端
ChannelFuture future = bs.connect(host, port).sync();
// 等待连接关闭
future.channel().closeFuture().sync();
}finally {
workersGroup.shutdownGracefully();
}
}
}
将字节转化成实体
代码:实体
public class UnixTime {
private final long value;
public UnixTime() {
this(System.currentTimeMillis() / 1000L + 2208988800L);
}
public UnixTime(long value) {
this.value = value;
}
public long value(){
return value;
}
@Override
public String toString() {
return new Date((value() - 2208988800L) * 1000L).toString();
}
}
代码:编码器(编码解析数据时使用)
public class TimeEncoder extends ChannelOutboundHandlerAdapter {
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
UnixTime m = (UnixTime) msg;
ByteBuf encoded = ctx.alloc().buffer(4);
encoded.writeInt((int) m.value());
ctx.write(encoded,promise);
}
}
代码3:解码器(解码数据时使用)
public class TimeDecoder extends ByteToMessageDecoder {
@Override
protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
if (byteBuf.readableBytes()<4){
return;
}
list.add(new UnixTime(byteBuf.readUnsignedInt()));
}
}
总结
- NioEventLoopGroup():1.NioEventLoopGroup是一个处理 I/O 操作的多线程事件循环。
- new ServerBootstrap():2.ServerBootstrap是一个设置服务器的辅助类。使用来设置服务器Channel。
- serverBootstrap.channel(NioServerSocketChannel.class):3.在这里,我们指定使用NioServerSocketChannel用于实例化新Channel接受传入连接的类。指定使用扫描类型的channel。
- serverBootstrap.childHandler():是一个特殊的ChannelInitializer处理程序,帮助用户配置一个新的Channel。
- ch.pipeline().addLast():添加通道中的处理器,主要业务写在里面
- serverBootstrap.option():设置特定于Channel实现的参数,如设置套接字选项。
- .bind(port).sync();// 绑定端口异步启动
- future.channel().closeFuture().sync():关闭服务器