1.客户端

①HelloClient.java

public class HelloClient {
	public static String host = "127.0.0.1";
	     public static int port = 7878;

	     /**
	      * @param args
	      * @throws InterruptedException
	      * @throws IOException
	      */
	     public static void main(String[] args) throws InterruptedException, IOException {
	         EventLoopGroup workGroup = new NioEventLoopGroup();
	         try {
	             Bootstrap b = new Bootstrap();
	             b.group(workGroup)
	             .channel(NioSocketChannel.class)
	             .handler(new HelloClientInitializer());

	             // 连接服务端
	             ChannelFuture future = b.connect(host, port).sync();

	             // 控制台输入
	             BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
	             for (;;) {
	                 String line = in.readLine();
	                 if (line == null) {
	                     continue;
	                 }
	                 /*
	                  * 向服务端发送在控制台输入的文本 并用"\r\n"结尾
	                  * 之所以用\r\n结尾 是因为我们在handler中添加了 DelimiterBasedFrameDecoder 帧解码。
	                  * 这个解码器是一个根据\n符号位分隔符的解码器。所以每条消息的最后必须加上\n否则无法识别和解码
	                  * */
	                 future.channel().writeAndFlush(line + "\r\n");
	             }
	         } finally {
	             // The connection is closed automatically on shutdown.
	        	 workGroup.shutdownGracefully();
	         }
	     }
}

②HelloClientInitializer.java

主要功能是完成客户端的编解码工作

public class HelloClientInitializer extends ChannelInitializer<SocketChannel> {

	     protected void initChannel(SocketChannel ch) throws Exception {
	         ChannelPipeline pipeline = ch.pipeline();

	         /*
	          * 这个地方的 必须和服务端对应上。否则无法正常解码和编码
	          *
	          * 解码和编码 我将会在下一张为大家详细的讲解。再次暂时不做详细的描述
	          *
	          * */
	         pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
	         pipeline.addLast("decoder", new StringDecoder());
	         pipeline.addLast("encoder", new StringEncoder());

	         // 客户端的逻辑
	         pipeline.addLast("handler", new HelloClientHandler());
	    }

}

③ HelloClientHandler.java

业务处理类,主要有三个方法

客户端建立连接时调用:channelActive方法

客户端接收服务端消息时调用:channelRead0方法

连接断开时调用:channelInactive方法

public class HelloClientHandler extends SimpleChannelInboundHandler<String> {
	     @Override
	     protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {

	         System.out.println("Server say : " + msg);
	     }

	     @Override
	     public void channelActive(ChannelHandlerContext ctx) throws Exception {
	         System.out.println("Client active ");
	         super.channelActive(ctx);
	     }

	     @Override
	     public void channelInactive(ChannelHandlerContext ctx) throws Exception {
	         System.out.println("Client close ");
	         super.channelInactive(ctx);
	     }
}

2.服务端

①HelloServer.java

public class HelloServer {
	 /**
     * 服务端监听的端口地址
     */
    private static final int portNumber = 7878;

    public static void main(String[] args) throws InterruptedException {
    	//第一个线程组用于接收client连接
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        //第二个线程组用于具体的业务处理
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
        	//创建一个辅助类Boosatrap用于对Server进行一系列的配置
            ServerBootstrap b = new ServerBootstrap();
            //将两个线程组加入进来
            b.group(bossGroup, workerGroup);
            //指定使用NioServerSocketChannel这种类型的通道
            b.channel(NioServerSocketChannel.class);
            //一定要使用childHandler绑定具体的事件处理器
            b.childHandler(new HelloServerInitializer());

            //SocketChannel通道的配置项(保持连接)
            b.option(ChannelOption.SO_KEEPALIVE, true);

            // 服务器绑定端口监听
            ChannelFuture f = b.bind(portNumber).sync();
            // 监听服务器关闭监听
            f.channel().closeFuture().sync();

            // 可以简写为
            /* b.bind(portNumber).sync().channel().closeFuture().sync(); */
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

②HelloServerInitializer.java

主要功能是完成服务端的编解码工作

public class HelloServerInitializer extends ChannelInitializer<SocketChannel> {
	     @Override
	     protected void initChannel(SocketChannel ch) throws Exception {
	         ChannelPipeline pipeline = ch.pipeline();

	         // 以("\n")为结尾分割的 解码器
	         pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));

	         // 字符串解码 和 编码
	         pipeline.addLast("decoder", new StringDecoder());
	         pipeline.addLast("encoder", new StringEncoder());

	         // 自己的逻辑Handler
	         pipeline.addLast("handler", new HelloServerHandler());
	     }
}

③HelloServerHandler.java

服务端的业务处理类,主要包括channelRead0(),channelActive()方法

channelActive()建立连接时触发

channelRead0()接收客户端消息

public class HelloServerHandler extends SimpleChannelInboundHandler<String> {
	     @Override
	     protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
	         // 收到消息直接打印输出
	         System.out.println(ctx.channel().remoteAddress() + " Say : " + msg);

	         // 返回客户端消息 - 我已经接收到了你的消息
	         ctx.writeAndFlush("Received your message !\n");
	     }

	     /*
	      *
	      * 覆盖 channelActive 方法 在channel被启用的时候触发 (在建立连接的时候)
	      *
	      * channelActive 和 channelInActive 在后面的内容中讲述,这里先不做详细的描述
	      * */
	     @Override
	     public void channelActive(ChannelHandlerContext ctx) throws Exception {

	         System.out.println("RamoteAddress : " + ctx.channel().remoteAddress() + " active !");

	         ctx.writeAndFlush( "Welcome to " + InetAddress.getLocalHost().getHostName() + " service!\n");

	         super.channelActive(ctx);
	     }
}

netty基本用法的更多相关文章

  1. Netty如何实现Reactor模式

    在前面的文章中(Reactor模型详解),我们讲解了Reactor模式的各种演变形式,本文主要讲解的则是Netty是如何实现Reactor模式的.这里关于Netty实现的Reactor模式,需要说明的 ...

  2. elasticsearch节点间通信的基础transport

    在前一篇中我们分析了cluster的一些元素.接下来的章节会对cluster的运作机制做详细分析.本节先分析一些transport,它是cluster间通信的基础.它有两种实现,一种是基于netty实 ...

  3. Netty学习笔记(二)——netty组件及其用法

    1.Netty是 一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端. 原生NIO存在的问题 1) NIO的类库和API繁杂,使用麻烦:需要熟练掌握Selector.Se ...

  4. netty用法总结

    /**decoder和encoder,如果不需要解析,就使用系统的 * ch.pipeline().addLast(new StringDecoder()); * ch.pipeline().addL ...

  5. 基于Netty打造RPC服务器设计经验谈

    自从在园子里,发表了两篇如何基于Netty构建RPC服务器的文章:谈谈如何使用Netty开发实现高性能的RPC服务器.Netty实现高性能RPC服务器优化篇之消息序列化 之后,收到了很多同行.园友们热 ...

  6. (二)Netty源码学习笔记之服务端启动

    尊重原创,转载注明出处,原文地址:http://www.cnblogs.com/cishengchongyan/p/6129971.html  本文将不会对netty中每个点分类讲解,而是一个服务端启 ...

  7. ElasticSearch的基本用法与集群搭建

    一.简介 ElasticSearch和Solr都是基于Lucene的搜索引擎,不过ElasticSearch天生支持分布式,而Solr是4.0版本后的SolrCloud才是分布式版本,Solr的分布式 ...

  8. Netty系列之Netty百万级推送服务设计要点

    1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...

  9. Netty权威指南

    Netty权威指南(异步非阻塞通信领域的经典之作,国内首本深入剖析Netty的著作,全面系统讲解原理.实战和源码,带你完美进阶Netty工程师.) 李林锋 著   ISBN 978-7-121-233 ...

随机推荐

  1. Day4_生成器_三元表达式_列表解析_生成器表达式

    生成器:在函数内部包含yield关键,那么该函数执行的结果就是生成器. 生成器就是迭代器. def func(): print('first') yield 111111 print('second' ...

  2. Mybatis 系列1

    第一篇教程, 就先简单地写个demo, 一起来认识一下mybatis吧. 为了方便,我使用了maven, 至于maven怎么使用, 我就不做介绍了.没用过maven的, 也不影响阅读. 一.Mybat ...

  3. 彪悍开源的分析数据库-ClickHouse

    https://zhuanlan.zhihu.com/p/22165241 今天介绍一个来自俄罗斯的凶猛彪悍的分析数据库:ClickHouse,它是今年6月开源,俄语社区为主,好酒不怕巷子深. 本文内 ...

  4. 基于Kurento的WebRTC移动视频群聊技术方案

    说在前面的话:视频实时群聊天有三种架构: Mesh架构:终端之间互相连接,没有中心服务器,产生的问题,每个终端都要连接n-1个终端,每个终端的编码和网络压力都很大.群聊人数N不可能太大. Router ...

  5. centos/linux 禁止root用户远程登录

    注意:在禁止root等前要建立一个用户用来远程登录,否则退出后无法通过远程登录服务器. 编辑 /etc/ssh/sshd_config 文件 更改参数 PermitRootLogin yes 为 Pe ...

  6. PyQt5实现界面跳转

    网上关于PyQt5的教程很少,特别是界面跳转这一块儿,自己研究了半天,下来和大家分享一下 一.首先是主界面 1 # -*- coding: utf-8 -*- # Form implementatio ...

  7. Yii2表单提交(带文件上传)

    今天写一个php的表单提交接口,除了基本的字符串数据,还带文件上传,不用说前端form标签内应该有这些属性 <form enctype="multipart/form-data&quo ...

  8. AUTOSAR分层-MCAL辨析

    8. AUTOSAR中MCAL虽然包含各种drvier,但毕竟是AL即抽象层,不应包含architecture和device特定的信息.应该只包含模型定义,不包含实现细节.   AUTOSAR文档中的 ...

  9. 基于Kafka Connect框架DataPipeline可以更好地解决哪些企业数据集成难题?

    DataPipeline已经完成了很多优化和提升工作,可以很好地解决当前企业数据集成面临的很多核心难题. 1. 任务的独立性与全局性. 从Kafka设计之初,就遵从从源端到目的的解耦性.下游可以有很多 ...

  10. 全面认识openstack:OpenStack架构详解

    OpenStack构架知识梳理   OpenStack既是一个社区,也是一个项目和一个开源软件,提供开放源码软件,建立公共和私有云,它提供了一个部署云的操作平台或工具集,其宗旨在于:帮助组织运行为虚拟 ...