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. docker的安装和技巧

    工作了有一段时间,开发环境中需要docker环境,但是docker一直不算很熟,之前一直是利用yum安装,但是yum安装真的很费劲,所以总结了一些经验给大家: 1,利用yum直接安装 官网是直接给了y ...

  2. Python笔记之 - 一张截图诠释"文件读写" !

    Python笔记之 - 一张截图诠释"文件读写" ! 源代码如下: # 文件读写 str_test1 = "先创建txt文件再写入内容: 我是大帅哥" # wi ...

  3. How to change from default to alternative Python version on Debian Linux

    https://linuxconfig.org/how-to-change-from-default-to-alternative-python-version-on-debian-linux You ...

  4. Microsoft源代码注释语言(SAL)提供设置批注

    Microsoft源代码注释语言(SAL)提供设置批注可以使用描述的功能如何使用其参数,它对其假设并确保它使其在完成. 批注可标头文件 <sal.h>定义. Visual Studio C ...

  5. IDEA 的maven项目打jar 编写UDF 在hive端运行 (全过程,有录制的操作视频)

    一.       前提准备 服务端hive搭建完成,可以正常创建访问表 本地端使用的IDE是Intellij IDEA(我的是2017版本,老版本需要支持创建maven项目) ,并且电脑有网. 二.  ...

  6. Ocelot中文文档-架构图

    Ocelot 针对的是,使用.net运行微服务和面向服务架构,并且需要一个统一的入口来访问他们系统的人群. 特别是,我想要与IdentityServer和令牌轻松集成. Ocelot是一组有特定顺序的 ...

  7. webstorm配置eslint【标记错误,修复错误】

    项目中经常用到eslint语法,结合个人经验,用webstorm配置eslint "文件"->"默认设置"->"语言&框架&quo ...

  8. 七个人生工具:SWOT、PDCA、6W2H、SMART、WBS、时间管理、二八原则

    本文为转载 心理导读:今天为大家分享几个实用的工具,来源网络. SWOT分析法 Strengths:优势 Weaknesses:劣势 Opportunities:机会 Threats:威胁 意义:帮您 ...

  9. Dubbo学习-源码学习

    Dubbo概述 dubbo框架提供多协议远程调用,服务提供方可以是分布式部署.dubbo框架可以很简单的帮我们实现微服务. 此处援引官网上图片 dubbo分为客户端和服务提供方 服务方将服务注册到注册 ...

  10. Laravel 框架 基础(一)

    Laravel 框架 laravel 5.2 在 5.1 基础上继续改进和优化,添加了许多新的功能特性:多认证驱动支持.隐式模型绑定.简化 Eloquent 全局作用域.可选择的认证脚手架.中间件组. ...