http://blog.csdn.net/u013252773/article/details/21046697

本文是学习Netty的第一篇文章,主要对Netty的Server和Client间的通讯机制进行验证。

Server与Client建立连接后,会执行以下的步骤:

1、Client向Server发送消息:Are you ok?

2、Server接收客户端发送的消息,并打印出来。

3、Server端向客户端发送消息:I am ok!

4、Client接收Server端发送的消息,并打印出来,通讯结束。

涉及到的类有4个:

1、HelloServer :server类,启动Netty server

2、HelloServerInHandler:server的handler,接收客户端消息,并向客户端发送消息

3、HelloClient:client类,建立于Netty server的连接

4、HelloClientIntHandler:client的handler,接收server端的消息,并向服务端发送消息

1、HelloServer代码如下:

  1. package com.guowl.testserver;
  2. import io.netty.bootstrap.ServerBootstrap;
  3. import io.netty.channel.ChannelFuture;
  4. import io.netty.channel.ChannelInitializer;
  5. import io.netty.channel.ChannelOption;
  6. import io.netty.channel.EventLoopGroup;
  7. import io.netty.channel.nio.NioEventLoopGroup;
  8. import io.netty.channel.socket.SocketChannel;
  9. import io.netty.channel.socket.nio.NioServerSocketChannel;
  10. public class HelloServer {
  11. public void start(int port) throws Exception {
  12. EventLoopGroup bossGroup = new NioEventLoopGroup();
  13. EventLoopGroup workerGroup = new NioEventLoopGroup();
  14. try {
  15. ServerBootstrap b = new ServerBootstrap();
  16. b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
  17. .childHandler(new ChannelInitializer<SocketChannel>() {
  18. @Override
  19. public void initChannel(SocketChannel ch)
  20. throws Exception {
  21. // 注册handler
  22. ch.pipeline().addLast(new HelloServerInHandler());
  23. }
  24. }).option(ChannelOption.SO_BACKLOG, 128)
  25. .childOption(ChannelOption.SO_KEEPALIVE, true);
  26. ChannelFuture f = b.bind(port).sync();
  27. f.channel().closeFuture().sync();
  28. } finally {
  29. workerGroup.shutdownGracefully();
  30. bossGroup.shutdownGracefully();
  31. }
  32. }
  33. public static void main(String[] args) throws Exception {
  34. HelloServer server = new HelloServer();
  35. server.start(8000);
  36. }
  37. }

2、HelloServerInHandler代码如下:

  1. package com.guowl.testserver;
  2. import io.netty.buffer.ByteBuf;
  3. import io.netty.channel.ChannelHandlerContext;
  4. import io.netty.channel.ChannelInboundHandlerAdapter;
  5. import org.slf4j.Logger;
  6. import org.slf4j.LoggerFactory;
  7. // 该handler是InboundHandler类型
  8. public class HelloServerInHandler extends ChannelInboundHandlerAdapter {
  9. private static Logger logger = LoggerFactory
  10. .getLogger(HelloServerInHandler.class);
  11. @Override
  12. public void channelRead(ChannelHandlerContext ctx, Object msg)
  13. throws Exception {
  14. logger.info("HelloServerInHandler.channelRead");
  15. ByteBuf result = (ByteBuf) msg;
  16. byte[] result1 = new byte[result.readableBytes()];
  17. // msg中存储的是ByteBuf类型的数据,把数据读取到byte[]中
  18. result.readBytes(result1);
  19. String resultStr = new String(result1);
  20. // 接收并打印客户端的信息
  21. System.out.println("Client said:" + resultStr);
  22. // 释放资源,这行很关键
  23. result.release();
  24. // 向客户端发送消息
  25. String response = "I am ok!";
  26. // 在当前场景下,发送的数据必须转换成ByteBuf数组
  27. ByteBuf encoded = ctx.alloc().buffer(4 * response.length());
  28. encoded.writeBytes(response.getBytes());
  29. ctx.write(encoded);
  30. ctx.flush();
  31. }
  32. @Override
  33. public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
  34. ctx.flush();
  35. }
  36. }

3、HelloClient代码如下:

  1. package com.guowl.testserver;
  2. import io.netty.bootstrap.Bootstrap;
  3. import io.netty.channel.ChannelFuture;
  4. import io.netty.channel.ChannelInitializer;
  5. import io.netty.channel.ChannelOption;
  6. import io.netty.channel.EventLoopGroup;
  7. import io.netty.channel.nio.NioEventLoopGroup;
  8. import io.netty.channel.socket.SocketChannel;
  9. import io.netty.channel.socket.nio.NioSocketChannel;
  10. public class HelloClient {
  11. public void connect(String host, int port) throws Exception {
  12. EventLoopGroup workerGroup = new NioEventLoopGroup();
  13. try {
  14. Bootstrap b = new Bootstrap();
  15. b.group(workerGroup);
  16. b.channel(NioSocketChannel.class);
  17. b.option(ChannelOption.SO_KEEPALIVE, true);
  18. b.handler(new ChannelInitializer<SocketChannel>() {
  19. @Override
  20. public void initChannel(SocketChannel ch) throws Exception {
  21. ch.pipeline().addLast(new HelloClientIntHandler());
  22. }
  23. });
  24. // Start the client.
  25. ChannelFuture f = b.connect(host, port).sync();
  26. // Wait until the connection is closed.
  27. f.channel().closeFuture().sync();
  28. } finally {
  29. workerGroup.shutdownGracefully();
  30. }
  31. }
  32. public static void main(String[] args) throws Exception {
  33. HelloClient client = new HelloClient();
  34. client.connect("127.0.0.1", 8000);
  35. }
  36. }

4、HelloClientIntHandler代码如下:

  1. package com.guowl.testserver;
  2. import io.netty.buffer.ByteBuf;
  3. import io.netty.channel.ChannelHandlerContext;
  4. import io.netty.channel.ChannelInboundHandlerAdapter;
  5. import org.slf4j.Logger;
  6. import org.slf4j.LoggerFactory;
  7. public class HelloClientIntHandler extends ChannelInboundHandlerAdapter {
  8. private static Logger logger = LoggerFactory.getLogger(HelloClientIntHandler.class);
  9. // 接收server端的消息,并打印出来
  10. @Override
  11. public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
  12. logger.info("HelloClientIntHandler.channelRead");
  13. ByteBuf result = (ByteBuf) msg;
  14. byte[] result1 = new byte[result.readableBytes()];
  15. result.readBytes(result1);
  16. System.out.println("Server said:" + new String(result1));
  17. result.release();
  18. }
  19. // 连接成功后,向server发送消息
  20. @Override
  21. public void channelActive(ChannelHandlerContext ctx) throws Exception {
  22. logger.info("HelloClientIntHandler.channelActive");
  23. String msg = "Are you ok?";
  24. ByteBuf encoded = ctx.alloc().buffer(4 * msg.length());
  25. encoded.writeBytes(msg.getBytes());
  26. ctx.write(encoded);
  27. ctx.flush();
  28. }
  29. }

通过上面简单的实例可以发现:

1、在没有任何encoder、decoder的情况下,Netty发送接收数据都是按照ByteBuf的形式,其它形式都是不合法的。

2、接收发送数据操作都是通过handler实现的,handler在netty中占据了非常重要的位置。

3、netty的handler是基于事件触发的,例如当client连接server成功后,client中的HelloClientIntHandler的channelActive方法会自动调用。

Netty4.0学习笔记系列之一:Server与Client的通讯的更多相关文章

  1. Netty4.0学习笔记系列之四:混合使用coder和handler

    Handler如何使用在前面的例子中已经有了示范,那么同样是扩展自ChannelHandler的Encoder和Decoder,与Handler混合后又是如何使用的?本文将通过一个实际的小例子来展示它 ...

  2. Netty4.0学习笔记系列之二:Handler的执行顺序(转)

    http://blog.csdn.net/u013252773/article/details/21195593 Handler在netty中,无疑占据着非常重要的地位.Handler与Servlet ...

  3. Netty4.0学习笔记系列之三:构建简单的http服务(转)

    http://blog.csdn.net/u013252773/article/details/21254257 本文主要介绍如何通过Netty构建一个简单的http服务. 想要实现的目的是: 1.C ...

  4. Netty4.0学习笔记系列之二:Handler的执行顺序

    Handler在netty中,无疑占据着非常重要的地位.Handler与Servlet中的filter很像,通过Handler可以完成通讯报文的解码编码.拦截指定的报文.统一对日志错误进行处理.统一对 ...

  5. Apache Ignite 学习笔记(三): Ignite Server和Client节点介绍

    在前两篇文章中,我们把Ignite集群当做一个黑盒子,用二进制包自带的脚本启动Ignite节点后,我们用不同的客户端连接上Ignite进行操作,展示了Ignite作为一个分布式内存缓存,内存数据库的基 ...

  6. SQLServer学习笔记系列2

    一.写在前面的话 继上一次SQLServer学习笔记系列1http://www.cnblogs.com/liupeng61624/p/4354983.html以后,继续学习Sqlserver,一步一步 ...

  7. 步步为营 SharePoint 开发学习笔记系列总结

    转:http://www.cnblogs.com/springyangwc/archive/2011/08/03/2126763.html 概要 为时20多天的sharepoint开发学习笔记系列终于 ...

  8. Redis 学习笔记系列文章之 Redis 的安装与配置 (一)

    1. 介绍 Redis is an open source (BSD licensed), in-memory data structure store, used as database, cach ...

  9. WebService学习笔记系列(二)

    soap(简单对象访问协议),它是在http基础之上传递xml格式数据的协议.soap协议分为两个版本,soap1.1和soap1.2. 在学习webservice时我们有一个必备工具叫做tcpmon ...

随机推荐

  1. Windows内核之线程的调度,优先级,亲缘性

    1 调度 Windows不是实时操作系统,它是抢占式多线程操作系统.在如果全部优先级同样的情况下,CPU对线程的调度原则是每隔20m就会切换到下一个线程,依据Context中的IP和SP来接着运行上次 ...

  2. linux下mysql配置文件my.cnf详解

    basedir = path 使用给定目录作为根目录(安装目录). character-sets-dir = path 给出存放着字符集的目录. datadir = path 从给定目录读取数据库文件 ...

  3. IntelliJ Idea 常用快捷键列表(精简版)

    查找快捷键: Ctrl+N 查找类 Ctrl+shift+N 查找文件 Ctrl+B 找变量来源 Ctrl+E 最近打开的文件 Ctrl+Alt+B 选中方法的实现 Ctrl+F7  选中方法(属性. ...

  4. 10.11 noip模拟试题

    4题均为128M,1s 1. 锻炼计划(exercise.pas) 身体是革命的本钱,OIers不要因为紧张的学习和整天在电脑前而忽视了健康问题.小x设计了自己的锻炼计划,但他不知道这个计划是否可行, ...

  5. php三个执行命令函数

    今天第一次知道php也可以执行window命令: exec system echo ``  两个是反的单引号 通过个人测试是可以的,貌似只能在本地

  6. iframe的缺点与优点?

    iframe是一种框架,也是一种很常见的网页嵌入方式. iframe的优点: iframe能够原封不动的把嵌入的网页展现出来. 如果有多个网页引用iframe,那么你只需要修改iframe的内容,就可 ...

  7. Linux命令:chmod命令

    chmod命令:改变文件或目录的存取权限 #权限代号 -r 文件被读取 4 -w 文件被写入 2 -x 文件被执行 1 #权限范围 -u 文件所有者 -g 文件所有者所在组 -o 其他 -a 全部 # ...

  8. hdoj 1060

    代码: #include <stdio.h>#include <math.h> int main(){    int t;    while(scanf("%d&qu ...

  9. SGU 119.Magic pairs

    题意: 对于给出的一个整数N,和一对(A0,B0) 找到所有的整数对(A,B)满足 : 对于任意 X,Y 当 A0 * X + B0 * Y 能被 N 整除时 A * X + B * Y 也能被 N ...

  10. 【POJ1151】【扫描线+线段树】Atlantis

    Description There are several ancient Greek texts that contain descriptions of the fabled island Atl ...