前言

因为以前在项目中使用过Mina框架,感受到了该框架的强大之处。于是在业余时间也学习了一下Netty。因为Netty的主要版本是Netty3和Netty4(Netty5已经被取消了),所以我就直接学习Netty4。在本文中演示的就是Netty的一个简单demo。

开发准备

Netty4的官方网站是:http://netty.io/
本文使用的是Netty4.1。
由于Netty4.1版本需要JDK1.7,在使用JDK1.6时,会有一些bug,所以推荐使用JDK1.7。

因为Netty和Mina都是Trustin Lee的作品,所以在很多方面都十分相似,他们线程模型也是基本一致,采用了Reactors in threads模型,即Main Reactor + Sub Reactors的模式。

所以在开发上,很多都可以相互借鉴。

服务端

首先完成Netty服务端相关开发,和Mina一样。
主要由两个部分组成: 配置服务端的基本信息以及实现业务逻辑处理。
如果需要,还有filter过滤器。

服务端代码

  1. import io.netty.bootstrap.ServerBootstrap;
  2. import io.netty.channel.ChannelFuture;
  3. import io.netty.channel.EventLoopGroup;
  4. import io.netty.channel.nio.NioEventLoopGroup;
  5. import io.netty.channel.socket.nio.NioServerSocketChannel;
  6. /**
  7. *
  8. * Title: NettyServer
  9. * Description: Netty服务端
  10. * Version:1.0.0
  11. * @author Administrator
  12. * @date 2017-8-31
  13. */
  14. public class NettyServer {
  15. private static final int port = 6789; //设置服务端端口
  16. private static EventLoopGroup group = new NioEventLoopGroup(); // 通过nio方式来接收连接和处理连接
  17. private static ServerBootstrap b = new ServerBootstrap();
  18. /**
  19. * Netty创建全部都是实现自AbstractBootstrap。
  20. * 客户端的是Bootstrap,服务端的则是 ServerBootstrap。
  21. **/
  22. public static void main(String[] args) throws InterruptedException {
  23. try {
  24. b.group(group);
  25. b.channel(NioServerSocketChannel.class);
  26. b.childHandler(new NettyServerFilter()); //设置过滤器
  27. // 服务器绑定端口监听
  28. ChannelFuture f = b.bind(port).sync();
  29. System.out.println("服务端启动成功...");
  30. // 监听服务器关闭监听
  31. f.channel().closeFuture().sync();
  32. } finally {
  33. group.shutdownGracefully(); ////关闭EventLoopGroup,释放掉所有资源包括创建的线程
  34. }
  35. }
  36. }

服务端业务逻辑

  1. import java.net.InetAddress;
  2. import java.util.Date;
  3. import io.netty.channel.ChannelHandlerContext;
  4. import io.netty.channel.SimpleChannelInboundHandler;
  5. /**
  6. *
  7. * Title: HelloServerHandler
  8. * Description: 服务端业务逻辑
  9. * Version:1.0.0
  10. * @author Administrator
  11. * @date 2017-8-31
  12. */
  13. public class NettyServerHandler extends SimpleChannelInboundHandler<String> {
  14. /*
  15. * 收到消息时,返回信息
  16. */
  17. @Override
  18. protected void channelRead0(ChannelHandlerContext ctx, String msg)
  19. throws Exception {
  20. // 收到消息直接打印输出
  21. System.out.println("服务端接受的消息 : " + msg);
  22. if("quit".equals(msg)){//服务端断开的条件
  23. ctx.close();
  24. }
  25. Date date=new Date();
  26. // 返回客户端消息
  27. ctx.writeAndFlush(date+"\n");
  28. }
  29. /*
  30. * 建立连接时,返回消息
  31. */
  32. @Override
  33. public void channelActive(ChannelHandlerContext ctx) throws Exception {
  34. System.out.println("连接的客户端地址:" + ctx.channel().remoteAddress());
  35. ctx.writeAndFlush("客户端"+ InetAddress.getLocalHost().getHostName() + "成功与服务端建立连接! \n");
  36. super.channelActive(ctx);
  37. }
  38. }

服务端过滤器

  1. import io.netty.channel.ChannelInitializer;
  2. import io.netty.channel.ChannelPipeline;
  3. import io.netty.channel.socket.SocketChannel;
  4. import io.netty.handler.codec.DelimiterBasedFrameDecoder;
  5. import io.netty.handler.codec.Delimiters;
  6. import io.netty.handler.codec.string.StringDecoder;
  7. import io.netty.handler.codec.string.StringEncoder;
  8. /**
  9. *
  10. * Title: HelloServerInitializer
  11. * Description: Netty 服务端过滤器
  12. * Version:1.0.0
  13. * @author Administrator
  14. * @date 2017-8-31
  15. */
  16. public class NettyServerFilter extends ChannelInitializer<SocketChannel> {
  17. @Override
  18. protected void initChannel(SocketChannel ch) throws Exception {
  19. ChannelPipeline ph = ch.pipeline();
  20. // 以("\n")为结尾分割的 解码器
  21. ph.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
  22. // 解码和编码,应和客户端一致
  23. ph.addLast("decoder", new StringDecoder());
  24. ph.addLast("encoder", new StringEncoder());
  25. ph.addLast("handler", new NettyServerHandler());// 服务端业务逻辑
  26. }
  27. }

客户端

客户端的主要工作是
1,连接到服务端
2,向服务端发送数据数据
3,处理服务端返回的数据
4,关闭连接
而且客户端相关代码也和服务端类似。

客户端

  1. import io.netty.bootstrap.Bootstrap;
  2. import io.netty.channel.Channel;
  3. import io.netty.channel.EventLoopGroup;
  4. import io.netty.channel.nio.NioEventLoopGroup;
  5. import io.netty.channel.socket.nio.NioSocketChannel;
  6. import java.io.IOException;
  7. /**
  8. *
  9. * Title: NettyClient
  10. * Description: Netty客户端
  11. * Version:1.0.0
  12. * @author Administrator
  13. * @date 2017-8-31
  14. */
  15. public class NettyClient {
  16. public static String host = "127.0.0.1"; //ip地址
  17. public static int port = 6789; //端口
  18. /// 通过nio方式来接收连接和处理连接
  19. private static EventLoopGroup group = new NioEventLoopGroup();
  20. private static Bootstrap b = new Bootstrap();
  21. private static Channel ch;
  22. /**
  23. * Netty创建全部都是实现自AbstractBootstrap。
  24. * 客户端的是Bootstrap,服务端的则是 ServerBootstrap。
  25. **/
  26. public static void main(String[] args) throws InterruptedException, IOException {
  27. System.out.println("客户端成功启动...");
  28. b.group(group);
  29. b.channel(NioSocketChannel.class);
  30. b.handler(new NettyClientFilter());
  31. // 连接服务端
  32. ch = b.connect(host, port).sync().channel();
  33. star();
  34. }
  35. public static void star() throws IOException{
  36. String str="Hello Netty";
  37. ch.writeAndFlush(str+ "\r\n");
  38. System.out.println("客户端发送数据:"+str);
  39. }
  40. }

客户端业务逻辑实现

  1. import io.netty.channel.ChannelHandlerContext;
  2. import io.netty.channel.SimpleChannelInboundHandler;
  3. /**
  4. *
  5. * Title: NettyClientHandler
  6. * Description: 客户端业务逻辑实现
  7. * Version:1.0.0
  8. * @author Administrator
  9. * @date 2017-8-31
  10. */
  11. public class NettyClientHandler extends SimpleChannelInboundHandler<String> {
  12. @Override
  13. protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
  14. System.out.println("客户端接受的消息: " + msg);
  15. }
  16. //
  17. @Override
  18. public void channelActive(ChannelHandlerContext ctx) throws Exception {
  19. System.out.println("正在连接... ");
  20. super.channelActive(ctx);
  21. }
  22. @Override
  23. public void channelInactive(ChannelHandlerContext ctx) throws Exception {
  24. System.out.println("连接关闭! ");
  25. super.channelInactive(ctx);
  26. }
  27. }

客户端过滤器

  1. import io.netty.channel.ChannelInitializer;
  2. import io.netty.channel.ChannelPipeline;
  3. import io.netty.channel.socket.SocketChannel;
  4. import io.netty.handler.codec.DelimiterBasedFrameDecoder;
  5. import io.netty.handler.codec.Delimiters;
  6. import io.netty.handler.codec.string.StringDecoder;
  7. import io.netty.handler.codec.string.StringEncoder;
  8. /**
  9. *
  10. * Title: NettyClientFilter
  11. * Description: Netty客户端 过滤器
  12. * Version:1.0.0
  13. * @author Administrator
  14. * @date 2017-8-31
  15. */
  16. public class NettyClientFilter extends ChannelInitializer<SocketChannel> {
  17. @Override
  18. protected void initChannel(SocketChannel ch) throws Exception {
  19. ChannelPipeline ph = ch.pipeline();
  20. /*
  21. * 解码和编码,应和服务端一致
  22. * */
  23. ph.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
  24. ph.addLast("decoder", new StringDecoder());
  25. ph.addLast("encoder", new StringEncoder());
  26. ph.addLast("handler", new NettyClientHandler()); //客户端的逻辑
  27. }
  28. }

效果实现图

服务端

客户端

demo教程到这里就结束了,如果有什么问题,欢迎提出!

该项目我放在github上了,有兴趣的可以看看!https://github.com/xuwujing/Netty

Netty4 学习笔记之一:客户端与服务端通信 demo的更多相关文章

  1. Docker学习笔记 - Docker客户端和服务端

    学习内容: Docker客户端和服务端的通讯方式:client和自定义程序 Docker客户端和服务端的连接方式:socket 演示Docker客户端和服务端之间用remote-api通讯:nc   ...

  2. FastSocket学习笔记~再说客户端与服务端的组成

    废话多说 很久之前,我写过几篇FastSocket的文章,基本属于使用的方法,而缺乏对概念的总结讲解,而本讲就是弥补一下上几讲的不足,将核心的模块再说说,再谈谈,再聊聊! 首先FastSocket由C ...

  3. Netty4 学习笔记之四: Netty HTTP服务的实现

    前言 目前主流的JAVA web 的HTTP服务主要是 springMVC和Struts2,更早的有JSP/servlet. 在学习Netty的时候,发现Netty 也可以作HTTP服务,于是便将此整 ...

  4. Android BLE与终端通信(三)——客户端与服务端通信过程以及实现数据通信

    Android BLE与终端通信(三)--客户端与服务端通信过程以及实现数据通信 前面的终究只是小知识点,上不了台面,也只能算是起到一个科普的作用,而同步到实际的开发上去,今天就来延续前两篇实现蓝牙主 ...

  5. 基于开源SuperSocket实现客户端和服务端通信项目实战

    一.课程介绍 本期带给大家分享的是基于SuperSocket的项目实战,阿笨在实际工作中遇到的真实业务场景,请跟随阿笨的视角去如何实现打通B/S与C/S网络通讯,如果您对本期的<基于开源Supe ...

  6. Netty入门之客户端与服务端通信(二)

    Netty入门之客户端与服务端通信(二) 一.简介 在上一篇博文中笔者写了关于Netty入门级的Hello World程序.书接上回,本博文是关于客户端与服务端的通信,感觉也没什么好说的了,直接上代码 ...

  7. Python进阶----SOCKET套接字基础, 客户端与服务端通信, 执行远端命令.

    Python进阶----SOCKET套接字基础, 客户端与服务端通信, 执行远端命令. 一丶socket套接字 什么是socket套接字: ​ ​  ​ 专业理解: socket是应用层与TCP/IP ...

  8. netty-3.客户端与服务端通信

    (原) 第三篇,客户端与服务端通信 以下例子逻辑: 如果客户端连上服务端,服务端控制台就显示,XXX个客户端地址连接上线. 第一个客户端连接成功后,客户端控制台不显示信息,再有其它客户端再连接上线,则 ...

  9. Netty4 学习笔记之二:客户端与服务端心跳 demo

    前言 在上一篇Netty demo 中,了解了Netty中的客户端和服务端之间的通信.这篇则介绍Netty中的心跳. 之前在Mina 中心跳的使用是通过继承 KeepAliveMessageFacto ...

随机推荐

  1. python中列表 元组 字典 集合的区别

    列表 元组 字典 集合的区别是python面试中最常见的一个问题.这个问题虽然很基础,但确实能反映出面试者的基础水平. (1)列表 什么是列表呢?我觉得列表就是我们日常生活中经常见到的清单.比如,统计 ...

  2. sort与qsort的用法,建议使用sort

    做ACM题的时候,排序是一种经常要用到的操作.如果每次都自己写个冒泡之类的O(n^2)排序,不但程序容易超时,而且浪费宝贵的比赛时间,还很有可能写错.STL里面有个sort函数,可以直接对数组排序,复 ...

  3. Oracle DG测试failover和后续恢复报告

    Oracle DG测试failover和后续恢复报告 一.概述 二.验证过程: 2.1 A库异常关闭 2.2 B库进行failover切换为新主库 2.3 要求C库成为新主库的备库 2.4 要求A库成 ...

  4. ASP.NET MVC5+EF6+EasyUI 后台管理系统(86)-日程管理-fullcalendar插件用法

    前言 本文分享fullcalendar用法,最后面提供代码下载 说到日程管理,基于JQuery的插件FullCalendar当之无愧,完整的API稳定和调用方式,非常易于扩展!可以用于系统的个人历程管 ...

  5. 多线程编程学习一(Java多线程的基础).

    一.进程和线程的概念 进程:一次程序的执行称为一个进程,每个 进程有独立的代码和数据空间,进程间切换的开销比较大,一个进程包含1—n个线程.进程是资源分享的最小单位. 线程:同一类线程共享代码和数据空 ...

  6. Linux平台 Oracle 12cR2 RAC安装Part1:准备工作

    Linux平台 Oracle 12cR2 RAC安装Part1:准备工作 一.实施前期准备工作 1.1 服务器安装操作系统 1.2 Oracle安装介质 1.3 共享存储规划 1.4 网络规范分配 二 ...

  7. 散列表(拉链法与线性探测法)Java实现

    package practice; import java.security.Principal; import java.util.Scanner; import edu.princeton.cs. ...

  8. struts.xml如何加载到及配置问题

    今天项目做客户化处理,看到struts.xml,突然间想不起来这个文件从哪里加载的了,真是越学越回去了.这里记录下. web工程启动的时候,系统会加载web.xml文件,在这个时候会加载Spring的 ...

  9. chrome开发工具指南(十四)

    模拟和测试其他浏览器 您的任务不只局限于确保网站在 Chrome 和 Android 上出色运行.即使 Device Mode 可以模拟 iPhone 等多种其他设备,我们仍鼓励您查看其他浏览器模拟解 ...

  10. pip 警告!The default format will switch to columns in the future

    pip警告! DEPRECATION: The default format will switch to columns in the future. You can use --format=(l ...