服务端代码示例

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;public class TimeServer {public void bind(int port) throws Exception {//配置服务端的NIO线程组//NioEventLoopGroup是个线程组,它包含了一组NIO线程,专门用于网络事件的处理,//实际上它们就是Reactor线程组。//这里创建两个的原因是一个用于服务端接受客户端的连接,另一个用于进行SocketChannel的网络读写。EventLoopGroup bossGroup = new NioEventLoopGroup();EventLoopGroup workerGroup = new NioEventLoopGroup();try {//创建ServerBootstrap对象,它是Netty用于启动NIO服务端的辅助启动类,目的是降低服务端的开发复杂度。ServerBootstrap b = new ServerBootstrap();//调用ServerBootstrap的group方法,将两个NIO线程组当作入参传递到ServerBootstrap中。//接着设置创建的Channel为NioServerSocketChannel,它的功能对应于JDK NIO类库中的ServerSocketChannel类。//然后配置NioServerSocketChannel的TCP参数,此处将它的backlog设置为1024,//最后绑定I/O事件的处理类ChildChannelHandler,它的作用类似于Reactor模式中的handler类,//主要用于处理网络I/O事件,例如记录日志、对消息进行编解码等。
            b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 1024).childHandler(new ChildChannelHandler());//绑定端口,同步等待成功//服务端启动辅助类配置完成之后,调用它的bind方法绑定监听端口//随后,调用它的同步阻塞方法sync等待绑定操作完成。//完成之后Netty会返回一个ChannelFuture,它的功能类似于JDK的java.util.concurrent.Future,主要用于异步操作的通知回调。ChannelFuture f = b.bind(port).sync();//等待服务端监听端口关闭//使用f.channel().closeFuture().sync()方法进行阻塞,等待服务端链路关闭之后main函数才退出。
            f.channel().closeFuture().sync();} finally {//优雅退出,释放线程池资源//调用NIO线程组的shutdownGracefully进行优雅退出,它会释放跟shutdownGracefully相关联的资源。
            bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}private class ChildChannelHandler extends ChannelInitializer {@Overrideprotected void initChannel(Channel channel) throws Exception {channel.pipeline().addLast(new TimeServerHandler());}}public static void main(String[] args) throws Exception {new TimeServer().bind(8080);}
}import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;//TimeServerHandler继承自ChannelHandlerAdapter,它用于对网络事件进行读写操作
//通常我们只需要关注channelRead和exceptionCaught方法。
public class TimeServerHandler extends ChannelHandlerAdapter {@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {//做类型转换,将msg转换成Netty的ByteBuf对象。//ByteBuf类似于JDK中的java.nio.ByteBuffer 对象,不过它提供了更加强大和灵活的功能。ByteBuf buf = (ByteBuf) msg;//通过ByteBuf的readableBytes方法可以获取缓冲区可读的字节数,//根据可读的字节数创建byte数组byte[] req = new byte[buf.readableBytes()];//通过ByteBuf的readBytes方法将缓冲区中的字节数组复制到新建的byte数组中
        buf.readBytes(req);//通过new String构造函数获取请求消息。String body = new String(req, "UTF-8");System.out.println("The time server receive order : " + body);//如果是"QUERY TIME ORDER"则创建应答消息,String currentTime = "QUERY TIME ORDER".equalsIgnoreCase(body) ? new java.util.Date(System.currentTimeMillis()).toString() : "BAD ORDER";ByteBuf resp = Unpooled.copiedBuffer(currentTime.getBytes());//通过ChannelHandlerContext的write方法异步发送应答消息给客户端。
        ctx.write(resp);}@Overridepublic void channelReadComplete(ChannelHandlerContext ctx) throws Exception {//调用了ChannelHandlerContext的flush方法,它的作用是将消息发送队列中的消息写入到SocketChannel中发送给对方。//从性能角度考虑,为了防止频繁地唤醒Selector进行消息发送,//Netty的write方法并不直接将消息写入SocketChannel中,调用write方法只是把待发送的消息放到发送缓冲数组中,//再通过调用flush方法,将发送缓冲区中的消息全部写到SocketChannel中。
        ctx.flush();}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {//当发生异常时,关闭ChannelHandlerContext,释放和ChannelHandlerContext相关联的句柄等资源。
        ctx.close();}
}

客户端代码示例:

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;public class TimeClient {public void connect(int port, String host) throws Exception {// 配置客户端NIO线程组//首先创建客户端处理I/O读写的NioEventLoop Group线程组EventLoopGroup group = new NioEventLoopGroup();try {//继续创建客户端辅助启动类Bootstrap,随后需要对其进行配置。//与服务端不同的是,它的Channel需要设置为NioSocketChannel//然后为其添加handler,此处为了简单直接创建匿名内部类,实现initChannel方法,//其作用是当创建NioSocketChannel成功之后,//在初始化它的时候将它的ChannelHandler设置到ChannelPipeline中,用于处理网络I/O事件。Bootstrap b = new Bootstrap();b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true).handler(new ChannelInitializer() {@Overrideprotected void initChannel(Channel channel) throws Exception {channel.pipeline().addLast(new TimeClientHandler());}});// 发起异步连接操作//客户端启动辅助类设置完成之后,调用connect方法发起异步连接,//然后调用同步方法等待连接成功。ChannelFuture f = b.connect(host, port).sync();// 等待客户端链路关闭//当客户端连接关闭之后,客户端主函数退出.
            f.channel().closeFuture().sync();} finally {// 优雅退出,释放NIO线程组//在退出之前,释放NIO线程组的资源。
            group.shutdownGracefully();}}public static void main(String[] args) throws Exception {new TimeClient().connect(8080, "127.0.0.1");}
}import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;//重点关注三个方法:channelActive、channelRead和exceptionCaught。
public class TimeClientHandler extends ChannelHandlerAdapter {private final ByteBuf firstMessage;
public TimeClientHandler() {byte[] req = "QUERY TIME ORDER".getBytes();firstMessage = Unpooled.buffer(req.length);firstMessage.writeBytes(req);}//当客户端和服务端TCP链路建立成功之后,Netty的NIO线程会调用channelActive方法
    @Overridepublic void channelActive(ChannelHandlerContext ctx) {//发送查询时间的指令给服务端//调用ChannelHandlerContext的writeAndFlush方法将请求消息发送给服务端。
        ctx.writeAndFlush(firstMessage);}//当服务端返回应答消息时,channelRead方法被调用
    @Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg)throws Exception {//从Netty的ByteBuf中读取并打印应答消息。ByteBuf buf = (ByteBuf) msg;byte[] req = new byte[buf.readableBytes()];buf.readBytes(req);String body = new String(req, "UTF-8");System.out.println("Now is : " + body);}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {// 释放资源//当发生异常时,打印异常日志,释放客户端资源。
        ctx.close();}
}

pom.xml

        <dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>5.0.0.Alpha1</version></dependency>

Netty 入门示例相关推荐

  1. 用java写个简单的直播强求_全网最简单易懂的Netty入门示例,再不会用Netty我直播吃翔...

    //server引导类 ServerBootstrap serverBootstrap = new ServerBootstrap(); //boss 对应 IOServer.java 中的接受新连接 ...

  2. Netty入门与实战教程

    前言:都说Netty是Java程序员必须要掌握的一项技能,带着不止要知其然还要知其所以然的目的,在慕课上找了一个学习Netty源码的教程,看了几章后着实有点懵逼.虽然用过Netty,并且在自己的个人网 ...

  3. [WCF编程]1.WCF入门示例

    一.WCF是什么? Windows Communication Foundation(WCF)是由微软开发的一系列支持数据通信的应用程序框架,整合了原有的windows通讯的 .net Remotin ...

  4. Netty入门教程——认识Netty

    什么是Netty? Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架. Netty 是一个广泛使用的 Java 网络编程框架(N ...

  5. BizTalk 2006 简单入门示例程序(附源项目文件下载)

    BizTalk 2006 简单入门示例程序(附源项目文件下载) 为初学BizTalk Server 2006的开发人员,提供一个简单入门的示例程序,包括一个Receive Port.Send Port ...

  6. Apache Camel框架入门示例

    2019独角兽企业重金招聘Python工程师标准>>> Apache Camel是Apache基金会下的一个开源项目,它是一个基于规则路由和中介引擎,提供企业集成模式的Java对象的 ...

  7. OUYA游戏开发核心技术剖析OUYA游戏入门示例——StarterKit

    第1章  OUYA游戏入门示例--StarterKit StarterKit是一个多场景的游戏示例,也是OUYA官方推荐给入门开发者分析的第一个完整游戏示例.本章会对StarterKit做详细介绍,包 ...

  8. python爬虫入门实例-终于领会python爬虫入门示例

    随着人工智能 大数据的火热 Python成为了广大科学家和普通大众的学习语言.在学习Python的过程中 有很多人感到迷茫 不知道自己该从什么地方入手,今天我们就来说一些新手该如何学习Python编程 ...

  9. 【Unity 3D 游戏开发】Unity3D 入门 - 工作区域介绍 与 入门示例

    一. 工作区域详解 1. Scence视图 (场景设计面板) scence视图简介 : 展示创建的游戏对象, 可以对所有的游戏对象进行 移动, 操作 和 放置; -- 示例 : 创建一个球体, 控制摄 ...

最新文章

  1. C语言程序设计第一节课作业
  2. 利用 libvirt 和 Linux 审计子系统跟踪 KVM 客户机
  3. Oracle 数据类型及存储方式(袁光东 原创)
  4. Android 自定义控件圆形图案
  5. 4月24 利用shell脚本添加环境变量
  6. linux 系统调试工具,Linux 系统调试...
  7. arcgis批量裁剪影像tif流程_ArcGIS超级工具SPTOOLS-影像的批量裁剪和批量合并
  8. css下标怎么打,css如何显示文字的上标和下标
  9. Win10下使用nvm安装多个版本node.js
  10. 在word中在方框里打钩
  11. kubectl template 一个例子
  12. 最近看到一篇文章拿来跟午饭们分享--养生之道补肾气
  13. 【深度学习】:详解目标检测YOLO V1(You Only Look Once)算法
  14. 云与瘦客户机 未来IT数据安全延续
  15. 苹果CMS海螺模板V16魔改版2.0修复bug分享给大家
  16. 怀念到哭泣、再美也伤
  17. E-puck2机器人系列教程
  18. CSS3基础入门03
  19. CSS基础综合案例1-新闻
  20. 华清远见C语言笔试题,华清远见C语言学习笔记五

热门文章

  1. iOS UITest之加载其他应用
  2. 建博客的原因。。。。
  3. 构建nodejs环境
  4. [C++] stack和queue的常用函数
  5. vue结合Promise及async实现高效开发。
  6. 爬虫神器xpath的用法(一)
  7. Func与Action
  8. android 自定义 styleable 属性
  9. Jquery 复选框全选与反选点击执行一次然后失效解决方案
  10. ldd -r xxx.so命令的重要作用------见招拆招地解决缺库问题(undefined symbol)