本文来做一个Netty的入门程序,即Netty的hello word入门级程序

文章目录

  • 概述
  • 导入Netty依赖
  • 服务端
    • 创建服务端
    • 自定义服务端 ChannelHandler 处理消息
  • 客户端
    • 创建客户端
    • 自定义客户端 ChannelHandler 处理消息
  • 运行程序
  • 本文小结

概述

在本节中,我们将构建一个完整的的 Netty 客户端和服务器。下图显示了连接到服务器的多个并发的客户端。在理论上,客户端可以支持的连接数只受限于使用的 JDK 版本中的制约:


导入Netty依赖

新建一个 Maven 项目,并导入 Netty 4.x 依赖:

<dependencies><dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.42.Final</version></dependency>
</dependencies>

详细可见官网 :https://netty.io/downloads.html


服务端

我们可以通过 ServerBootstrap 来引导我们启动一个简单的 Netty 服务端,为此,你必须要为其指定下面三类属性:

  • 线程组(一般需要两个线程组,一个负责处理客户端的连接,一个负责具体的 IO 处理)
  • IO 模型(BIO/NIO)
  • 自定义 ChannelHandler (处理客户端发过来的数据并返回数据给客户端)

创建服务端

public final class HelloServer {private  final int port;public HelloServer(int port) {this.port = port;}private void start() throws InterruptedException {// 1.bossGroup 线程用于接收连接,workerGroup 线程用于具体的处理EventLoopGroup bossGroup = new NioEventLoopGroup(1);EventLoopGroup workerGroup = new NioEventLoopGroup();try {// 2.创建服务端启动引导/辅助类:ServerBootstrapServerBootstrap b = new ServerBootstrap();// 3.给引导类配置两大线程组,确定了线程模型b.group(bossGroup, workerGroup)// (非必备)打印日志.handler(new LoggingHandler(LogLevel.INFO))// 4.指定 IO 模型为 NIO.channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {@Overridepublic void initChannel(SocketChannel ch) {ChannelPipeline p = ch.pipeline();// 5.可以自定义客户端消息的业务处理逻辑p.addLast(new HelloServerHandler());}});// 6.绑定端口,调用 sync 方法阻塞直到绑定完成ChannelFuture f = b.bind(port).sync();// 7.阻塞等待直到服务器Channel关闭 (closeFuture()方法获取Channel 的CloseFuture对象,然后调用sync()方法)f.channel().closeFuture().sync();} finally {// 8.优雅关闭相关线程组资源bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}public static void main(String[] args) throws InterruptedException {new HelloServer(8080).start();}}


自定义服务端 ChannelHandler 处理消息

HelloServerHandler.java:

@Sharable
public class HelloServerHandler extends ChannelInboundHandlerAdapter {// 服务端接收客户端发送的数据并响应@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) {try {ByteBuf in = (ByteBuf) msg;System.out.println("message from Client:" + in.toString(CharsetUtil.UTF_8));// 发送消息给客户端ctx.writeAndFlush(Unpooled.copiedBuffer("Hello from Server", CharsetUtil.UTF_8));} finally {ReferenceCountUtil.release(msg);}}// 处理客户端消息发生异常@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {// Close the connection when an exception is raised.cause.printStackTrace();ctx.close();}
}

这个逻辑处理器继承自ChannelInboundHandlerAdapter 并重写了下面 2 个方法:

  • channelRead() :服务端接收客户端发送数据调用的方法
  • exceptionCaught() :处理客户端消息发生异常的时候被调用

客户端

创建客户端

创建客户端

public final class HelloClient {private final String host;private final int port;private final String message;public HelloClient(String host, int port, String message) {this.host = host;this.port = port;this.message = message;}private void start() throws InterruptedException {// 1.创建一个 NioEventLoopGroup 对象实例EventLoopGroup group = new NioEventLoopGroup();try {// 2.创建客户端启动引导/辅助类:BootstrapBootstrap b = new Bootstrap();// 3.指定线程组b.group(group)// 4.指定 IO 模型.channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {@Overridepublic void initChannel(SocketChannel ch) throws Exception {ChannelPipeline p = ch.pipeline();// 5.这里可以自定义消息的业务处理逻辑p.addLast(new HelloClientHandler(message));}});// 6.尝试建立连接ChannelFuture f = b.connect(host, port).sync();// 7.等待连接关闭(阻塞,直到Channel关闭)f.channel().closeFuture().sync();} finally {group.shutdownGracefully();}}public static void main(String[] args) throws Exception {new HelloClient("127.0.0.1",8080, "Hello from Client").start();}
}


自定义客户端 ChannelHandler 处理消息

HelloClientHandler.java:

@Sharable
public class HelloClientHandler extends ChannelInboundHandlerAdapter {private final String message;public HelloClientHandler(String message) {this.message = message;}// 客户端和服务端的连接建立之后就会被调用@Overridepublic void channelActive(ChannelHandlerContext ctx) {System.out.println("Client send msg to Server: " + message);ctx.writeAndFlush(Unpooled.copiedBuffer(message, CharsetUtil.UTF_8));}// 客户端接收服务端发送的数据@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) {ByteBuf in = (ByteBuf) msg;try {System.out.println("Client receive msg from Server: " + in.toString(CharsetUtil.UTF_8));} finally {ReferenceCountUtil.release(msg);}}// 处理消息发生异常@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {cause.printStackTrace();ctx.close();}
}

这个逻辑处理器继承自 ChannelInboundHandlerAdapter,并且覆盖了下面三个方法:

  • channelActive() : 客户端和服务端的连接建立之后就会被调用
  • channelRead : 客户端接收服务端发送数据调用的方法
  • exceptionCaught : 处理消息发生异常的时候被调用

运行程序


本文小结

本文讲解了一个netty的入门程序。

第一个Netty应用相关推荐

  1. 《Netty In Action》第二章:第一个Netty程序

    2019独角兽企业重金招聘Python工程师标准>>> 源码地址: GitHub 2.3 编写一个应答服务器 写一个Netty服务器主要由两部分组成: 配置服务器功能,如线程.端口 ...

  2. 1、张龙netty学习 第一个netty服务端

    张龙netty学习 第一个netty服务端 public class TestServer {public static void main(String[] args) throws Excepti ...

  3. 一起来分解一个Netty应用

    ​前言 前面几篇博客主要介绍到了NIO针对网络IO场景相比较传统的Socket通信的优势,以及NIO在应用过程中线程模型的演化.从这篇博客开始我们一起来学习一个基于NIO实现的框架Netty,这是一个 ...

  4. Netty介绍 与第一个Netty实例

    官网:https://netty.io/ 以下内容大部分来自Netty官网内容 一.现有问题 现在我们使用通用应用程序或库来彼此通信.例如,我们经常使用HTTP客户端库从web服务器检索信息,并通过w ...

  5. WebSocket不同版本的三种握手方式以及一个Netty实现JAVA类

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 一.We ...

  6. Netty网络编程实战1,搭建第一个Netty服务器

    目录 一.Netty是什么 二.Hello Netty 1.主程序类MyNettyServerTest 2.初始化器MyNettyServerInitializer 3.自定义处理器MyNettySe ...

  7. 教你用 Netty 实现一个简单的 RPC!

    众所周知,dubbo 底层使用了 Netty 作为网络通讯框架,而 Netty 的高性能我们之前也分析过源码,对他也算还是比较了解了. 今天我们就自己用 Netty 实现一个简单的 RPC 框架. 1 ...

  8. Netty之实现一个简单的群聊系统

    要求 编写一个 Netty 群聊系统,实现服务器端和客户端之间的数据简单通讯(非阻塞) 实现多人群聊 服务器端:可以监测用户上线,离线,并实现消息转发功能 客户端:通过channel可以无阻塞发送消息 ...

  9. Netty报错 远程主机强迫关闭了一个现有的连接 异常

    百度百科的描述 Netty是由JBOSS提供的一个java开源框架,现为 Github上的独立项目.Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速开发高性能.高可靠性的网络服务器和客 ...

最新文章

  1. 二叉树的最小高度,最大高度(深度)和宽度
  2. php的const,php中const入门
  3. java文件读写的两种方式
  4. java 概率 算法_使用概率算法优化快速排序(JAVA)
  5. spring分布式事务示例_Spring声明式事务示例
  6. PS教程第十九课:移动工具
  7. linux命令history作用,Linux命令:history命令历史的管理及用法
  8. (STL,map)反片语
  9. javascript window Timing
  10. c语言不允许有常量的是,C语言试卷第10套含答案.doc-资源下载人人文库网
  11. Yii2.0 rules验证规则大全
  12. 人工智能在麻将领域能够战胜人类吗?
  13. GMaps.js - 轻松集成Google Maps的jQuery插件
  14. ajax返回功能,jquery – 记得ajax在点击返回按钮时添加的数据
  15. stat---文件状态信息结构体
  16. 实例化Spring容器的两种常用方式
  17. 二维平面中二维向量的叉乘 得到的向量,x、y方向上的分量必定为0
  18. C语言中TC20是什么意思,c语言tc20下载
  19. ASR - OpenAI whisper
  20. 有才而性缓,有智而气和

热门文章

  1. 极光推送---安卓Demo
  2. 桌面桌面虚拟化-Vmware horizon 7相关文件共享
  3. PHP数组合并+与array_merge的区别分析 对多个数组合并去重技巧
  4. SQL Server 分离与附加数据库
  5. jQuery零基础入门——(三)层级选择器
  6. exchange 2010申请分配证书服务提示:证书无效,不可用于exchange server
  7. 淘汰Hyper-V replication 拥抱Storage Replica
  8. Java什么时候提高境界支持async/await写法啊?
  9. [官版翻译]OpenStack centos版安装(二)
  10. MySQL去除查询结果重复值