http://blog.csdn.net/cxhzqhzq/article/details/6611977

Java的网络操作一直比较复杂,虽然说在加入NIO之后简单了些,但还不是我这些菜鸟玩得起的,由于存在大量低层操作和协议处理,所以在使用上面还是很难。迄今为止,还没有用NIO写出稳定可靠的网络操作,也许这和具体的应用需求较少也有关系吧。

大概也有人和我对NIO有同样的想法,他们最NIO进行了一些封装,所以就有了MIna和现在的Netty。

Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序[官方定义],整体来看其包含了以下内容:

1.提供了丰富的协议编解码支持,

2.实现自有的buffer系统,减少复制所带来的消耗,

3.整套channel的实现,

4.基于事件的过程流转以及完整的网络事件响应与扩展,

5.丰富的example。

有了Netty之后,网络编程最起码会大大简化,并且我们也不需要为性能问题担心,Netty并发两三万还是没什么太大问题的。已经有人进行过实验了。

本文主要是列举Netty初步使用的一个最基本的例子,具体的说明在代码中都有了,所以也不再重复。

java的学习是从Hello word开始的,Netty也从这里开始吧。
这里的例子比较简单,后面会慢慢的对Netty的一些复杂应用、Netty的原理进行一些解析。
1、ClientThread.java

[java] view plaincopyprint?
  1. package HelloWord;
  2. import static org.jboss.netty.channel.Channels.pipeline;
  3. import java.net.InetSocketAddress;
  4. import java.util.concurrent.Executors;
  5. import org.jboss.netty.bootstrap.ClientBootstrap;
  6. import org.jboss.netty.channel.ChannelFuture;
  7. import org.jboss.netty.channel.ChannelPipeline;
  8. import org.jboss.netty.channel.ChannelPipelineFactory;
  9. import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
  10. import org.jboss.netty.handler.codec.string.StringDecoder;
  11. import org.jboss.netty.handler.codec.string.StringEncoder;
  12. /**
  13. * 启动一个client线程,用来间歇性的发送消息
  14. * @author Ransom
  15. */
  16. public class ClientThread implements Runnable
  17. {
  18. private ChannelFuture future;
  19. public ChannelFuture getFuture()
  20. {
  21. return future;
  22. }
  23. public void setFuture(ChannelFuture future)
  24. {
  25. this.future = future;
  26. }
  27. @Override
  28. public void run()
  29. {
  30. /*
  31. * 实例化一个客户端Bootstrap实例,
  32. * NioClientSocketChannelFactory是Netty默认提供的。
  33. * 两个参数,一个是boss的线程池,一个是worker执行的线程池。
  34. * 两个线程池都使用了java.util.concurrent.Executors中的线程池来创建。
  35. */
  36. ClientBootstrap bootstrap = new ClientBootstrap(
  37. new NioClientSocketChannelFactory(
  38. Executors.newCachedThreadPool(),
  39. Executors.newCachedThreadPool()));
  40. /*
  41. * 设置piplineFactory,
  42. * 顾名思义,就是产生默认的pipline。
  43. *  pipline的实例是DefaultChannelPipeline
  44. *  提供了链式的事件通讯机制
  45. */
  46. bootstrap.setPipelineFactory(new ChannelPipelineFactory(){
  47. /*
  48. * (non-Javadoc)
  49. * @see org.jboss.netty.channel.ChannelPipelineFactory#getPipeline()
  50. */
  51. @Override
  52. public ChannelPipeline getPipeline() throws Exception
  53. {
  54. /*
  55. * 在DefaultChannelPipeline的过滤器 链中实现了
  56. * encode 、decode、handler
  57. * 其中encode实现自ChannelDownstreamHandler接口
  58. * decode、Handler实现自ChannelUpstreamHandler接口
  59. * 也就说明了在client发送消息的时候,默认按照顺序会先调用decode
  60. * 在client接收到响应的时候,会按照顺序调用encode和Handler。
  61. * 后面会有文章专门将ChannelDownstreamHandler和ChannelUpstreamHandler的调用顺序。
  62. */
  63. ChannelPipeline pipleline = pipeline();
  64. pipleline.addLast("encode", new StringEncoder());
  65. pipleline.addLast("decode", new StringDecoder());
  66. pipleline.addLast("handler", new Handler());
  67. return pipleline;
  68. }
  69. });
  70. /*
  71. * 与127.0.0.1建立长连接。
  72. */
  73. future = bootstrap.connect(new InetSocketAddress("127.0.0.1", 8080));
  74. }
  75. /**
  76. * 发送消息至server
  77. */
  78. public void sendMsg()
  79. {
  80. if(future==null) return;
  81. String s = "Hello Word!";
  82. future.getChannel().write(s);
  83. }
  84. }
package HelloWord;
import static org.jboss.netty.channel.Channels.pipeline;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.handler.codec.string.StringEncoder;
/**
* 启动一个client线程,用来间歇性的发送消息
* @author Ransom
*/
public class ClientThread implements Runnable
{
private ChannelFuture future;
public ChannelFuture getFuture()
{
return future;
}
public void setFuture(ChannelFuture future)
{
this.future = future;
}
@Override
public void run()
{
/*
* 实例化一个客户端Bootstrap实例,
* NioClientSocketChannelFactory是Netty默认提供的。
* 两个参数,一个是boss的线程池,一个是worker执行的线程池。
* 两个线程池都使用了java.util.concurrent.Executors中的线程池来创建。
*/
ClientBootstrap bootstrap = new ClientBootstrap(
new NioClientSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool()));
/*
* 设置piplineFactory,
* 顾名思义,就是产生默认的pipline。
*  pipline的实例是DefaultChannelPipeline
*  提供了链式的事件通讯机制
*/
bootstrap.setPipelineFactory(new ChannelPipelineFactory(){
/*
* (non-Javadoc)
* @see org.jboss.netty.channel.ChannelPipelineFactory#getPipeline()
*/
@Override
public ChannelPipeline getPipeline() throws Exception
{
/*
* 在DefaultChannelPipeline的过滤器 链中实现了
* encode 、decode、handler
* 其中encode实现自ChannelDownstreamHandler接口
* decode、Handler实现自ChannelUpstreamHandler接口
* 也就说明了在client发送消息的时候,默认按照顺序会先调用decode
* 在client接收到响应的时候,会按照顺序调用encode和Handler。
* 后面会有文章专门将ChannelDownstreamHandler和ChannelUpstreamHandler的调用顺序。
*/
ChannelPipeline pipleline = pipeline();
pipleline.addLast("encode", new StringEncoder());
pipleline.addLast("decode", new StringDecoder());
pipleline.addLast("handler", new Handler());
return pipleline;
}
});
/*
* 与127.0.0.1建立长连接。
*/
future = bootstrap.connect(new InetSocketAddress("127.0.0.1", 8080));
}
/**
* 发送消息至server
*/
public void sendMsg()
{
if(future==null) return;
String s = "Hello Word!";
future.getChannel().write(s);
}
}

2、Handler.java

[java] view plaincopyprint?
  1. package HelloWord;
  2. import org.jboss.netty.channel.ChannelHandlerContext;
  3. import org.jboss.netty.channel.ExceptionEvent;
  4. import org.jboss.netty.channel.MessageEvent;
  5. import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
  6. /**
  7. * client和server接收消息共用的handler
  8. * 由于两个都是继承自SimpleChannelUpstreamHandler,所以就写在一起了。
  9. * @author Ransom
  10. *
  11. */
  12. public class Handler extends SimpleChannelUpstreamHandler
  13. {
  14. public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
  15. throws Exception
  16. {
  17. System.out.println("recive message,message content:"+e.getMessage());
  18. }
  19. public void exceptionCaught(
  20. ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
  21. System.err.println("Client has a error,Error cause:"+e.getCause());
  22. e.getChannel().close();
  23. }
  24. }
package HelloWord;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
/**
* client和server接收消息共用的handler
* 由于两个都是继承自SimpleChannelUpstreamHandler,所以就写在一起了。
* @author Ransom
*
*/
public class Handler extends SimpleChannelUpstreamHandler
{
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
throws Exception
{
System.out.println("recive message,message content:"+e.getMessage());
}
public void exceptionCaught(
ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
System.err.println("Client has a error,Error cause:"+e.getCause());
e.getChannel().close();
}
}

3、Server.java

[java] view plaincopyprint?
  1. package HelloWord;
  2. import static org.jboss.netty.channel.Channels.pipeline;
  3. import java.net.InetSocketAddress;
  4. import java.util.concurrent.Executors;
  5. import org.jboss.netty.bootstrap.ServerBootstrap;
  6. import org.jboss.netty.channel.ChannelPipeline;
  7. import org.jboss.netty.channel.ChannelPipelineFactory;
  8. import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
  9. import org.jboss.netty.handler.codec.string.StringDecoder;
  10. import org.jboss.netty.handler.codec.string.StringEncoder;
  11. /**
  12. * 在本地8080端口启动netty服务
  13. * @author Ransom
  14. *
  15. */
  16. public class Server
  17. {
  18. public static void main(String[] args)
  19. {
  20. /*
  21. * server的注释和client类似,在这里就不重复了
  22. * 但是需要注意的是server初始化的是ServerBootstrap的实例
  23. * client初始化的是ClientBootstrap,两个是不一样的。
  24. * 里面的channelfactory也是NioServerSocketChannelFactory。
  25. */
  26. ServerBootstrap bootstrap = new ServerBootstrap(
  27. new NioServerSocketChannelFactory(
  28. Executors.newCachedThreadPool(),
  29. Executors.newCachedThreadPool()));
  30. bootstrap.setPipelineFactory(new ChannelPipelineFactory()
  31. {
  32. @Override
  33. public ChannelPipeline getPipeline() throws Exception
  34. {
  35. ChannelPipeline pipleline = pipeline();
  36. pipleline.addLast("encode", new StringEncoder());
  37. pipleline.addLast("decode", new StringDecoder());
  38. pipleline.addLast("handler", new Handler());
  39. return pipleline;
  40. }
  41. });
  42. bootstrap.bind(new InetSocketAddress(8080));
  43. }
  44. }
package HelloWord;
import static org.jboss.netty.channel.Channels.pipeline;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.handler.codec.string.StringEncoder;
/**
* 在本地8080端口启动netty服务
* @author Ransom
*
*/
public class Server
{
public static void main(String[] args)
{
/*
* server的注释和client类似,在这里就不重复了
* 但是需要注意的是server初始化的是ServerBootstrap的实例
* client初始化的是ClientBootstrap,两个是不一样的。
* 里面的channelfactory也是NioServerSocketChannelFactory。
*/
ServerBootstrap bootstrap = new ServerBootstrap(
new NioServerSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool()));
bootstrap.setPipelineFactory(new ChannelPipelineFactory()
{
@Override
public ChannelPipeline getPipeline() throws Exception
{
ChannelPipeline pipleline = pipeline();
pipleline.addLast("encode", new StringEncoder());
pipleline.addLast("decode", new StringDecoder());
pipleline.addLast("handler", new Handler());
return pipleline;
}
});
bootstrap.bind(new InetSocketAddress(8080));
}
}

4、HelloWordMain.java

[java] view plaincopyprint?
  1. package HelloWord;
  2. /**
  3. * Netty 初步之hello word的client入口
  4. * @author Ransom
  5. *
  6. */
  7. public class HelloWordMain
  8. {
  9. public static void main(String[] args)
  10. {
  11. ClientThread r = new ClientThread();
  12. Thread t = new Thread(r);
  13. t.setName("client thread");
  14. t.start();
  15. while(true)
  16. {
  17. try
  18. {
  19. Thread.sleep(3000);
  20. } catch (InterruptedException e)
  21. {
  22. // TODO Auto-generated catch block
  23. e.printStackTrace();
  24. }
  25. r.sendMsg();
  26. }
  27. }
  28. }

Netty初步之hello world相关推荐

  1. Netty框架初步学习

    初步看了一下Netty的代码构成,发现还是挺有意思的. 先看看如下几段代码: 服务端 package ServerNetty;import io.netty.bootstrap.ServerBoots ...

  2. Netty学习记录-初步认识Netty及I/O模型

    Netty学习记录 Netty简介 Netty特征 Netty架构结构图 Netty如今使用的场景 IO了解 BIO: BIO演变的NIO的过程 NIO: NIO三大核心(重点) NIO非阻塞网络编程 ...

  3. ktor框架用到了netty吗_教你如何构建异步服务器和客户端的 Kotlin 框架 Ktor

    Ktor 是一个使用 Kotlin 以最小的成本快速创建 Web 应用程序的框架. Ktor 是一个用于在连接系统(connected systems)中构建异步服务器和客户端的 Kotlin 框架. ...

  4. Netty Channel源码分析

    原文:https://wangwei.one/posts/netty-channel-source-analyse.html 前面,我们大致了解了Netty中的几个核心组件.今天我们就来先来介绍Net ...

  5. Netty堆外内存泄露排查与总结

    导读 Netty 是一个异步事件驱动的网络通信层框架,用于快速开发高可用高性能的服务端网络框架与客户端程序,它极大地简化了 TCP 和 UDP 套接字服务器等网络编程. Netty 底层基于 JDK ...

  6. Netty 简单服务器 (三)

    2019独角兽企业重金招聘Python工程师标准>>> 经过对Netty的基础认识,设计模型的初步了解,来写个测试,试试手感 上篇也说到官方推荐我们使用主从线程池模型,那就选择这个模 ...

  7. Netty入门官方例子

    学习分布式,正好看到Netty 是一个基于NIO的客户.服务器端编程框架,所以本着学习的态度去官网看了一下,官网例子,本着以后可以翻出来再看看的心态,把官网的第一个例子贴出来,也希望自己以后有一个可以 ...

  8. 当Tomcat遇上Netty,我这一系列神操作,同事看了拍手叫绝

    故事背景 嘀~嘀~嘀~,生产事故,内存泄漏! 昨天下午,突然收到运维的消息,分部某系统生产环境内存泄漏了,帮忙排查一下. 排查过程如下: 第一步,要日志 分部给到的异常日志大概是这样(鉴于公司规定禁止 ...

  9. Netty中集成Protobuf实现Java对象数据传递

    场景 Netty的Socket编程详解-搭建服务端与客户端并进行数据传输: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/1086 ...

最新文章

  1. sftp连不上服务器 vscode_VSCODE 【SFTP】 Code:3221225477 / 扩展宿主意外终止 解决方法...
  2. 时间字段 oracle 经验 设计,数据库设计与优化
  3. [SDWC2018 Day1]网格
  4. python 2x可以打么_Python打基础一定要吃透这68个内置函数
  5. 英语四六级听力考试选项技巧
  6. python123测验答案测验3_知到app数学分析3-3测验答案查询服务
  7. shell @ Linux (1)
  8. “Google只认钱!机器学习20年没进步”,CMU学者炮轰AI第一大厂
  9. 【Luogu3371】【模板】单源最短路径(SPFA)
  10. 自然数之和(leetcode 167)
  11. 帆软计算字符串中指定字符个数
  12. Day001 20210206
  13. 如何给光耦输入端限流
  14. android面试题之三(红黑联盟)
  15. 制作自己专属的抓包工具
  16. Spring—事务配置及mybatis整合
  17. php doctrine datetime,关于php:Doctrine 2.1 – datetime列的默认值
  18. Percona-XtraBackup系列一:安装 perl(Time::HiRes) is needed by percona-xtrabackup-2.2.10-1.el6.x86_64...
  19. 牛逼!手把手教你制作个人微信红包封面,保姆级红包封面制作教程
  20. 普华i-VirtualApp应用交付系统介绍

热门文章

  1. 【数据结构与算法】之深入解析“三数之和”的求解思路与算法示例
  2. 详解Python的*args和 **kwargs
  3. 大数据WEB阶段(十九)Threadlocal
  4. Java面向对象(五)abstract --- 抽象
  5. 【嵌入式】嵌入式天地博客汇总
  6. python实时数据流设计_Python读取实时数据流示例
  7. 如何用python开发游戏_手把手教你用Python完成一个控制台小游戏-阿里云开发者社区...
  8. POJ 1852 Ants O(n)
  9. muduo网络库学习(五)服务器监听类Acceptor及Tcp连接TcpConnection的建立与关闭
  10. SENet(Squeeze-and-Excitation Networks)