引言

前面我们介绍了网络一些基本的概念,虽然说这些很难吧,但是至少要做到理解吧。有了之前的基础,我们来正式揭开Netty这神秘的面纱就会简单很多。

服务端

public class PrintServer {public void bind(int port) throws Exception {EventLoopGroup bossGroup = new NioEventLoopGroup();                     //1EventLoopGroup workerGroup = new NioEventLoopGroup();                   //2try {ServerBootstrap b = new ServerBootstrap();                          //3b.group(bossGroup, workerGroup)                                     //4                                         .channel(NioServerSocketChannel.class)                      //5.option(ChannelOption.SO_BACKLOG, 1024)                     //6.childHandler(new ChannelInitializer<SocketChannel>() {     //7@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast(new PrintServerHandler());}});ChannelFuture f = b.bind(port).sync();              //8f.channel().closeFuture().sync();                   //9} finally {// 优雅退出,释放线程池资源bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}/*** @param args* @throws Exception*/public static void main(String[] args) throws Exception {int port = 8080;new TimeServer().bind(port);}
}

我们来分析一下上面的这段代码(下面的每一点对应上面的注释)

1~2:首先我们创建了两个NioEventLoopGroup实例,它是一个由Netty封装好的包含NIO的线程组。为什么创建两个?我想经过前面的学习大家应该都清楚了。对,因为Netty的底层是IO多路复用,bossGroup 是用于接收客户端的连接,原理就是一个实现的Selector的Reactor线程。而workerGroup用于进行SocketChannel的网络读写。

3:创建一个ServerBootstrap对象,可以把它想象成Netty的入口,通过这类来启动Netty,将所需要的参数传递到该类当中,大大降低了的开发难度。

4:将两个NioEventLoopGroup实例绑定到ServerBootstrap对象中。

5:创建Channel(典型的channel有NioSocketChannel,NioServerSocketChannel,OioSocketChannel,OioServerSocketChannel,EpollSocketChannel,EpollServerSocketChannel),这里创建的是NIOserverSocketChannel,它的功能可以理解为当接受到客户端的连接请求的时候,完成TCP三次握手,TCP物理链路建立成功。并将该“通道”与workerGroup线程组的某个线程相关联。

6:设置参数,这里设置的SO_BACKLOG,意思是客户端连接等待队列的长度为1024.

7:建立连接后的具体Handler。就是我们接受数据后的具体操作,例如:记录日志,对信息解码编码等。

8:绑定端口,同步等待成功

9:等待服务端监听端口关闭

绑定该服务端的Handler

public class PrintServerHandler extends ChannelHandlerAdapter {@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg)throws Exception {ByteBuf buf = (ByteBuf) msg;                                        //1byte[] req = new byte[buf.readableBytes()]; buf.readBytes(req); //将缓存区的字节数组复制到新建的req数组中String body = new String(req, "UTF-8");System.out.println(body);String response= "打印成功";ByteBuf resp = Unpooled.copiedBuffer(response.getBytes());                      ctx.write(resp);                                                    //2}   @Overridepublic void channelReadComplete(ChannelHandlerContext ctx) throws Exception {ctx.flush();                                                        //3}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {ctx.close();}
}

PrintServerHandler 继承 ChannelHandlerAdapter ,在这里它的功能为 打印客户端发来的数据并且返回客户端打印成功。

我们只需要实现channelRead,exceptionCaught,前一个为接受消息具体逻辑的实现,后一个为发生异常后的具体逻辑实现。

1:我们可以看到,接受的消息被封装为了Object ,我们将其转换为ByteBuf ,前一章的讲解中也说明了该类的作用。我们需要读取的数据就在该缓存类中。

2~3:我们将写好的数据封装到ByteBuf中,然后通过write方法写回到客户端,这里的3调用flush方法的作用为,防止频繁的发送数据,write方法并不直接将数据写入SocketChannel中,而是把待发送的数据放到发送缓存数组中,再调用flush方法发送数据。

客户端

public class PrintClient {public void connect(int port, String host) throws Exception {EventLoopGroup group = new NioEventLoopGroup();                 //1try {Bootstrap b = new Bootstrap();                              //2b.group(group)                                             //3.channel(NioSocketChannel.class)                        //4.option(ChannelOption.TCP_NODELAY, true)                //5.handler(new ChannelInitializer<SocketChannel>() {      //6@Overridepublic void initChannel(SocketChannel ch)               throws Exception {ch.pipeline().addLast(new PrintClientHandler());}});ChannelFuture f = b.connect(host, port).sync();             //7f.channel().closeFuture().sync();                           //8} finally {// 优雅退出,释放NIO线程组group.shutdownGracefully();}}/*** @param args* @throws Exception*/public static void main(String[] args) throws Exception {int port = 8080;new TimeClient().connect(port, "127.0.0.1");}
}

我们继续来分析一下上面的这段代码(下面的每一点对应上面的注释)

1:区别于服务端,我们在客户端只创建了一个NioEventLoopGroup实例,因为客户端你并不需要使用I/O多路复用模型,需要有一个Reactor来接受请求。只需要单纯的读写数据即可

2:区别于服务端,我们在客户端只需要创建一个Bootstrap对象,它是客户端辅助启动类,功能类似于ServerBootstrap。

3:将NioEventLoopGroup实例绑定到Bootstrap对象中。

4:创建Channel(典型的channel有NioSocketChannel,NioServerSocketChannel,OioSocketChannel,OioServerSocketChannel,EpollSocketChannel,EpollServerSocketChannel),区别与服务端,这里创建的是NIOSocketChannel.

5:设置参数,这里设置的TCP_NODELAY为true,意思是关闭延迟发送,一有消息就立即发送,默认为false。

6:建立连接后的具体Handler。注意这里区别与服务端,使用的是handler()而不是childHandler()。handler和childHandler的区别在于,handler是接受或发送之前的执行器;childHandler为建立连接之后的执行器。

7:发起异步连接操作

8:当代客户端链路关闭

绑定该客户端的Handler

public class PrintClientHandler extends ChannelHandlerAdapter {private static final Logger logger = Logger.getLogger(TimeClientHandler.class.getName());private final ByteBuf firstMessage;/*** Creates a client-side handler.*/public TimeClientHandler() {byte[] req = "你好服务端".getBytes();firstMessage = Unpooled.buffer(req.length);                                 //1firstMessage.writeBytes(req);}@Overridepublic void channelActive(ChannelHandlerContext ctx) {ctx.writeAndFlush(firstMessage);                                            //2             }@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg)              //3throws Exception {ByteBuf buf = (ByteBuf) msg;    byte[] req = new byte[buf.readableBytes()];buf.readBytes(req);String body = new String(req, "UTF-8");System.out.println("服务端回应消息 : " + body);}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {   //4// 释放资源System.out.println("Unexpected exception from downstream : "+ cause.getMessage());ctx.close();}
}

PrintClientHandler 继承 ChannelHandlerAdapter ,在这里它的功能为 发送数据并打印服务端发来的数据。

我们只需要实现channelActive,channelRead,exceptionCaught,第一个为建立连接后立即执行,后两个与一个为接受消息具体逻辑的实现,另一个为发生异常后的具体逻辑实现。

1:将发送的信息封装到ByteBuf中。

2:发送消息。

3:接受客户端的消息并打印

4:发生异常时,打印异常信息,释放客户端资源

总结

这是一个入门程序,对应前面所讲的I/O多路复用模型以及NIO的特性,能很有效的理解该模式的编程方式。如果这几段代码看着很费劲,那么可以看看之前博主的Netty基础系列。

如果博主哪里说得有问题,希望大家提出来,一起进步~

转载于:https://www.cnblogs.com/zhxiansheng/p/10830828.html

Netty入门系列(1) --使用Netty搭建服务端和客户端相关推荐

  1. Netty的Socket编程详解-搭建服务端与客户端并进行数据传输

    场景 Netty在IDEA中搭建HelloWorld服务端并对Netty执行流程与重要组件进行介绍: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article ...

  2. SuperSocket与Netty之实现protobuf协议,包括服务端和客户端

    今天准备给大家介绍一个c#服务器框架(SuperSocket)和一个c#客户端框架(SuperSocket.ClientEngine).这两个框架的作者是园区里面的江大渔. 首先感谢他的无私开源贡献. ...

  3. 《Netty权威指南 第2版》学习笔记(1)---服务端与客户端开发入门

    前言 Netty权威指南中以时间服务器为入门案例,演示了如何通过Netty完成了服务端与客户端之间的交互过程. 在开始使用Netty开发之前,先回顾一下使用NIO进行服务端开发的步骤. 创建Serve ...

  4. Netty实战 IM即时通讯系统(八)服务端和客户端通信协议编解码

    Netty实战 IM即时通讯系统(八)服务端和客户端通信协议编解码 零. 目录 IM系统简介 Netty 简介 Netty 环境配置 服务端启动流程 客户端启动流程 实战: 客户端和服务端双向通信 数 ...

  5. Netty的服务端和客户端

    通过简单代码实现服务端与服务端 本文章只做简单学习交流,如工作需要,请合理配置搭建. 详细讲解在代码注释中.上货!!!! 1.引入包 pom.xml中引入 <dependency>< ...

  6. netty tcp服务端主动断开客户端_【Netty】服务端和客户端

    欢迎关注公众号:[爱编程] 如果有需要后台回复2019赠送1T的学习资料哦!! 本文是基于Netty4.1.36进行分析 服务端 Netty服务端的启动代码基本都是如下: private void s ...

  7. Netty学习笔记(二) 实现服务端和客户端

    在Netty学习笔记(一) 实现DISCARD服务中,我们使用Netty和Python实现了简单的丢弃DISCARD服务,这篇,我们使用Netty实现服务端和客户端交互的需求. 前置工作 开发环境 J ...

  8. netty服务器返回信息关闭,netty4 服务端同步客户端返回的结果

    netty是一个异步通讯框架,在有的时候咱们想使用服务端向客户端发送消息,服务端同步等待客户端返回结果真进行下一步的业务逻辑操做.那要怎么作才能同步获取客户端返回的数据呢?这里我用到了JDK中的闭锁等 ...

  9. Netty即是服务端又是客户端,服务端和客户端相互对应

    Netty即是服务端又是客户端,服务端和客户端相互对应. 具体功能细节是: 上游有一个服务,会主动发送消息给我中间件平台.中间件平台既有服务端也有客户端.通过下游客户端连接进来的客户端和中间件传下去的 ...

最新文章

  1. Activity平移动画
  2. 【记忆断层、记忆裂痕】
  3. 2015 2020 r4烧录卡 区别_谁跑赢了沪深300?聪明指数全收益排名 2020-04-10
  4. Activiti源码 之工厂模式
  5. oracle crontab e,Linux运维知识之通过crontab -e编辑生成的定时任务,写在哪个文件中...
  6. mysql linux附加数据库文件夹,Linux全攻略--MySQL数据库配置与管理
  7. pdo一次插入多条数据的2种实现方式
  8. data2vec!统一模态的新里程碑
  9. python数据分析-如何在业余时学数据分析?
  10. 如何在 Mac 上的“照片”中更改和增强视频?
  11. web controls归档
  12. java解释器是什么_java编译器和解释器
  13. c语言的整形变量选择题,C语言选择题 (附答案)
  14. Python 的RS485 串口通讯
  15. vue 动态背景图片
  16. 全球人工智能产业链产业图谱
  17. 库克放大招啦!一张照片生成3D头像,新模型击败StyleGAN2!
  18. 测试工程师转开发希望大吗?
  19. java指针压缩临界值
  20. android刷机恢复出厂设置吗,安卓手机恢复出厂设置和双清有什么区别?

热门文章

  1. xBIM WeXplorer 设置模型颜色
  2. 给Clouderamanager集群里安装基于Hive的大数据实时分析查询引擎工具Impala步骤(图文详解)...
  3. 俄罗斯方块(结对作业)
  4. nyoj_518_取球游戏_201404161738
  5. tcp-ip协议详解二知识进阶
  6. 记本阶段建站心得,是走无限做垃圾站之路还是真正的开发之路
  7. ASP.NET弹出一个对话框
  8. html5 css3 卡片切换,HTML5之纯CSS3实现的tab标签切换
  9. 配置文件~/.ssh/config和/etc/ssh/ssh_config
  10. 字符集问题的初步探讨-乱码的产生