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. tomcat启动非常慢;连接oracle数据库失败,jdbc错误日志提示connection reset;测试主机间网络互通及数据库端口都正常

      [判断确认:这时候大家可能要去检查一下/dev/random 这个设备档案.可以用cat /dev/random 来看它的内容,如果你发现他一直没显示任何内容﹝可能是乱码数字之类的﹞,那就是它出问 ...

  2. 【转】H.264中的NAL技术

    NAL技术 1.NAL概述 NAL全称Network Abstract Layer,即网络抽象层.在H.264/AVC视频编码标准中,整个系统框架被分为了两个层面:视频编码层面(VCL)和网络抽象层面 ...

  3. Microsoft C++ 异常: std::system_error std::thread

    第一次使用std::thread,把之前项目里面的Windows的thread进行了替换,程序退出的然后发生了std::system_error. 经过调试,发现std::thread ,join了两 ...

  4. 爬取廖雪峰的python3教程

    从廖雪峰老师的python教程入门的,最近在看python爬虫,入手了一下 代码比较low,没有用到多线程和ip代理池 然后呢,由于robots.txt的限定,构建了一些user-agent,并放慢的 ...

  5. Vue、AngularJS 双向数据绑定解剖

    数据与视图的绑定与同步,最终体现在对数据的读写处理过程中,也就是 Object.defineProperty() 定义的数据 set.get 函数中.Vue 中对于的函数为 defineReactiv ...

  6. [ Java面试题 ] 集合篇

    1.ArrayList和Vector的区别 这两个类都实现了List接口(List接口继承了Collection接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动态的 ...

  7. vue UI库iview源码解析(2)

    上篇问题 在上篇<iview源码解析(1)>中的index.js 入口文件的源码中有一段代码有点疑惑: /** * 在浏览器环境下默认加载组件 */ // auto install if ...

  8. 算法训练 2的次幂表示(蓝桥杯C++写法)

    问题描述 任何一个正整数都可以用2进制表示,例如:137的2进制表示为10001001. 将这种2进制表示写成2的次幂的和的形式,令次幂高的排在前面,可得到如下表达式:137=2^7+2^3+2^0 ...

  9. idea 整合ssm 启动页404问题

  10. Python--Seaborn绘图和可视化--基本语法

    博客地址:http://www.cnblogs.com/yudanqu/ Seaborn是对matplotlib的extend,是一个数据可视化库,提供更高级的API封装,在应用中更加的方便灵活.下面 ...