Netty权威指南之Netty入门应用

亦凉 2023-10-16 21:49 91阅读 0赞

本章节需要学习的内容如下:

1、Netty开发环境搭建

2、服务端程序开发NettyServer

3、客户端程序开发NettyClient

第一节:Netty开发环境搭建

(1)、访问Netty的官网http://netty.io,从【Download】标签页下载netty-5.0.0.Alpha2.tar.bz2安装包,安装包不大,14.6M左右。下载完成后,如下截图:

Center

(2)、通过解压缩工具打开压缩工具,如以下截图:

Center 1

(3)、搭建Netty 应用工程,使用MyEclipse 10 创建普通的Java工程,同时创建Java源文件的package。

Center 2

(4)、创建第三方类库存放文件夹lib,同时将netty-all-5.0.0.Alpha2.jar文件复制到lib目录下。

Center 3

到此,Netty应用程序的开发环境已经搭建完毕。

第二节:Netty服务端开发

温故知新:在开始使用Netty开发服务端之前,先回顾一下使用NIO进行服务端开发步骤:

1、创建ServerSocketChannle,并配置它为非阻塞模式。

2、绑定监听,配置TCP参数。比如blocklog大小。

3、创建一个独立的IO线程,用于轮训多路复用器Selector。

4、创建Selector,将之前创建的ServerSocketChannle注册到Selector上,监听SelectKey.Accept.

5、启动IO线程,在循环体中执行Selector.select()方法,轮训就绪的Channle.

6、当轮训到就绪状态的Channle,需要对其判断,如果是SelectorKey.Accept状态,说明是新客户端接入,则调用ServerSocketChannle.accept()的方法接受新的客户端。

7、设置新接入的客户端的链路SocketChannle为非阻塞模式,配置其他的TCP参数。

8、将SocketChannle注册到Selector,监听OP_READ操作位。

9、如果轮训的Channle为OP_READ,则说明SocketChannle中有新的就绪的数据包需要读取,构造ByteBuff对象,读取数据包。

10、如果轮训的Channle的状态为OP_WRITE,说明还有数据没有发送完成,需要继续发送。

分析:一个简单的Java NIO服务端程序,如果我们选择使用Java JDK 的NIO库开发,竟然需要进过繁琐的十几步操作才能完成最基本的信息发送与接受,这也是我们选择Java NIO 开源框架的原因(Netty).

NettyServer.java

  1. package com.nio.server;
  2. import com.nio.handler.NettyServerHandler;
  3. import io.netty.bootstrap.ServerBootstrap;
  4. import io.netty.channel.ChannelFuture;
  5. import io.netty.channel.ChannelInitializer;
  6. import io.netty.channel.ChannelOption;
  7. import io.netty.channel.EventLoopGroup;
  8. import io.netty.channel.nio.NioEventLoopGroup;
  9. import io.netty.channel.socket.SocketChannel;
  10. import io.netty.channel.socket.nio.NioServerSocketChannel;
  11. /**
  12. * Created by vixuan-008 on 2015/6/19.
  13. */
  14. public class NettyServer {
  15. public static void main(String[] args)throws Exception{
  16. int port=17666;
  17. new NettyServer().bind(port);
  18. }
  19. public void bind(int port)throws Exception{
  20. //配置服务端的NIO线程池
  21. EventLoopGroup bossGroup=new NioEventLoopGroup();
  22. EventLoopGroup workGroup=new NioEventLoopGroup();
  23. try{
  24. ServerBootstrap b=new ServerBootstrap();
  25. b.group(bossGroup,workGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG,1024).childHandler(new NettyServerHandler());
  26. //绑定端口,等待同步成功
  27. ChannelFuture f=b.bind(port).sync();
  28. //等待服务端关闭监听端口
  29. f.channel().closeFuture().sync();
  30. }finally {
  31. //释放线程池资源
  32. bossGroup.shutdownGracefully();
  33. workGroup.shutdownGracefully();
  34. }
  35. }
  36. //添加内部类
  37. private class ChildChannelHandler extends ChannelInitializer<SocketChannel>{
  38. @Override
  39. protected void initChannel(SocketChannel socketChannel) throws Exception {
  40. socketChannel.pipeline().addLast(new NettyServerHandler());
  41. }
  42. }
  43. }

NettyServerHandler.java

  1. package com.nio.handler;
  2. import io.netty.buffer.ByteBuf;
  3. import io.netty.buffer.Unpooled;
  4. import io.netty.channel.ChannelHandlerAdapter;
  5. import io.netty.channel.ChannelHandlerContext;
  6. /**
  7. * Created by vixuan-008 on 2015/6/19.
  8. */
  9. public class NettyServerHandler extends ChannelHandlerAdapter {
  10. @Override
  11. public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
  12. ctx.close();
  13. }
  14. @Override
  15. public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
  16. ByteBuf buf=(ByteBuf)msg;
  17. byte[] req=new byte[buf.readableBytes()];
  18. buf.readBytes(req);
  19. String body=new String(req,"UTF-8");
  20. System.out.println("the server receiver data is:"+body);
  21. String currentTime="time".equalsIgnoreCase(body) ? new java.util.Date(System.currentTimeMillis()).toString():"no zuo no die";
  22. ByteBuf resp= Unpooled.copiedBuffer(currentTime.getBytes());
  23. ctx.write(resp);
  24. }
  25. @Override
  26. public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
  27. super.channelReadComplete(ctx);
  28. ctx.flush();
  29. }
  30. }

第三节:Netty客户端开发

NettyClient.java

  1. package com.nio.client;
  2. import com.nio.handler.NettyClientHandler;
  3. import io.netty.channel.ChannelFuture;
  4. import io.netty.channel.ChannelInitializer;
  5. import io.netty.channel.ChannelOption;
  6. import io.netty.channel.EventLoopGroup;
  7. import io.netty.channel.nio.NioEventLoopGroup;
  8. import io.netty.channel.socket.SocketChannel;
  9. import io.netty.channel.socket.nio.NioSocketChannel;
  10. /**
  11. * Created by vixuan-008 on 2015/6/19.
  12. */
  13. public class NettyClient {
  14. public static void main(String[] args)throws Exception{
  15. int port=17666;
  16. new NettyClient().connect(port,"127.0.0.1");
  17. }
  18. public void connect(int port,String host)throws Exception{
  19. //配置客户端NIO线程池
  20. EventLoopGroup workGroup=new NioEventLoopGroup();
  21. try{
  22. io.netty.bootstrap.Bootstrap b=new io.netty.bootstrap.Bootstrap();
  23. b.group(workGroup).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY,true).handler(new ChannelInitializer<SocketChannel>() {
  24. @Override
  25. protected void initChannel(SocketChannel socketChannel) throws Exception {
  26. socketChannel.pipeline().addLast(new NettyClientHandler());
  27. }
  28. });
  29. //发起异步连接操作
  30. ChannelFuture f=b.connect(host,port).sync();
  31. //等待客户端链路关闭
  32. f.channel().closeFuture().sync();
  33. }finally {
  34. //释放NIO 线程组
  35. workGroup.shutdownGracefully();
  36. }
  37. }
  38. }

NettyClientHandler.java

  1. package com.nio.handler;
  2. import io.netty.buffer.ByteBuf;
  3. import io.netty.buffer.Unpooled;
  4. import io.netty.channel.ChannelHandlerAdapter;
  5. import io.netty.channel.ChannelHandlerContext;
  6. /**
  7. * Created by vixuan-008 on 2015/6/19.
  8. */
  9. public class NettyClientHandler extends ChannelHandlerAdapter {
  10. private final ByteBuf message;
  11. public NettyClientHandler() {
  12. byte[] req="time".getBytes();
  13. message= Unpooled.buffer(req.length);
  14. message.writeBytes(req);
  15. }
  16. @Override
  17. public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
  18. ctx.close();
  19. }
  20. @Override
  21. public void channelActive(ChannelHandlerContext ctx) throws Exception {
  22. ctx.writeAndFlush(message);
  23. }
  24. @Override
  25. public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
  26. ByteBuf buf=(ByteBuf)msg;
  27. byte[] req=new byte[buf.readableBytes()];
  28. buf.readBytes(req);
  29. String body=new String(req,"UTF-8");
  30. System.out.println("this client receiver data is:"+body);
  31. }
  32. @Override
  33. public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
  34. }
  35. }

今天学习到此结束。

:

发表评论

表情:
评论列表 (有 0 条评论,91人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Netty权威指南文件传输

    本章相关知识点: 文件是最常见的数据源之一,在程序经常需要将数据存储到文件中,比如:图片文件、声音文件等数据文件。在实际使用中,文件都包含一个特定的格式,这个格式需要程序员根

    相关 Netty权威指南AIO编程

    由JDK1.7提供的NIO2.0新增了异步的套接字通道,它是真正的异步I/O,在异步I/O操作的时候可以传递信号变量,当操作完成后会回调相关的方法,异步I/o也被称为AIO,对