Java中的NIO是一种解决阻塞式IO问题的基本技术,但是NIO的编写对java程序员是有比较高的要求的。那么Netty就是一种简化操作的一个成熟的网络IO编程框架。这里简单介绍一个程序,代码是《netty in action》里面的,不过那个里面的实例有点问题,反正我没有跑成功,修改后成功。直接上代码:


一、服务器编写

  Server代码,监听连接

  1. package com.gerry.netty.server;
  2.  
  3. import io.netty.bootstrap.ServerBootstrap;
  4. import io.netty.channel.ChannelFuture;
  5. import io.netty.channel.ChannelInitializer;
  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.  
  11. public class EchoServer {
  12. private final int port;
  13.  
  14. public EchoServer(int port) {
  15. this.port = port;
  16. }
  17.  
  18. public void start() throws Exception {
  19. EventLoopGroup group = new NioEventLoopGroup();
  20. try {
  21. ServerBootstrap sb = new ServerBootstrap();
  22. sb.group(group) // 绑定线程池
  23. .channel(NioServerSocketChannel.class) // 指定使用的channel
  24. .localAddress(this.port)// 绑定监听端口
  25. .childHandler(new ChannelInitializer<SocketChannel>() { // 绑定客户端连接时候触发操作
  26.  
  27. @Override
  28. protected void initChannel(SocketChannel ch) throws Exception {
  29. System.out.println("connected...; Client:" + ch.remoteAddress());
  30. ch.pipeline().addLast(new EchoServerHandler()); // 客户端触发操作
  31. }
  32. });
  33. ChannelFuture cf = sb.bind().sync(); // 服务器异步创建绑定
  34. System.out.println(EchoServer.class + " started and listen on " + cf.channel().localAddress());
  35. cf.channel().closeFuture().sync(); // 关闭服务器通道
  36. } finally {
  37. group.shutdownGracefully().sync(); // 释放线程池资源
  38. }
  39. }
  40.  
  41. public static void main(String[] args) throws Exception {
  42. new EchoServer(65535).start(); // 启动
  43. }
  44. }

  具体的处理客户端连接的代码

  1. package com.gerry.netty.server;
  2.  
  3. import io.netty.buffer.Unpooled;
  4. import io.netty.channel.ChannelFutureListener;
  5. import io.netty.channel.ChannelHandlerContext;
  6. import io.netty.channel.ChannelInboundHandlerAdapter;
  7.  
  8. public class EchoServerHandler extends ChannelInboundHandlerAdapter {
  9. @Override
  10. public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
  11. System.out.println("server channelRead...; received:" + msg);
  12. ctx.write(msg);
  13. }
  14.  
  15. @Override
  16. public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
  17. System.out.println("server channelReadComplete..");
  18. // 第一种方法:写一个空的buf,并刷新写出区域。完成后关闭sock channel连接。
  19. ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
  20. //ctx.flush(); // 第二种方法:在client端关闭channel连接,这样的话,会触发两次channelReadComplete方法。
  21. //ctx.flush().close().sync(); // 第三种:改成这种写法也可以,但是这中写法,没有第一种方法的好。
  22. }
  23.  
  24. @Override
  25. public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
  26. System.out.println("server occur exception:" + cause.getMessage());
  27. cause.printStackTrace();
  28. ctx.close(); // 关闭发生异常的连接
  29. }
  30. }

二、客户端编写

  具体的连接代码

  1. package com.gerry.netty.client;
  2.  
  3. import io.netty.bootstrap.Bootstrap;
  4. import io.netty.channel.ChannelFuture;
  5. import io.netty.channel.ChannelInitializer;
  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.  
  11. import java.net.InetSocketAddress;
  12.  
  13. public class EchoClient {
  14. private final String host;
  15. private final int port;
  16.  
  17. public EchoClient() {
  18. this(0);
  19. }
  20.  
  21. public EchoClient(int port) {
  22. this("localhost", port);
  23. }
  24.  
  25. public EchoClient(String host, int port) {
  26. this.host = host;
  27. this.port = port;
  28. }
  29.  
  30. public void start() throws Exception {
  31. EventLoopGroup group = new NioEventLoopGroup();
  32. try {
  33. Bootstrap b = new Bootstrap();
  34. b.group(group) // 注册线程池
  35. .channel(NioSocketChannel.class) // 使用NioSocketChannel来作为连接用的channel类
  36. .remoteAddress(new InetSocketAddress(this.host, this.port)) // 绑定连接端口和host信息
  37. .handler(new ChannelInitializer<SocketChannel>() { // 绑定连接初始化器
  38. @Override
  39. protected void initChannel(SocketChannel ch) throws Exception {
  40. System.out.println("connected...");
  41. ch.pipeline().addLast(new EchoClientHandler());
  42. }
  43. });
  44. System.out.println("created..");
  45.  
  46. ChannelFuture cf = b.connect().sync(); // 异步连接服务器
  47. System.out.println("connected..."); // 连接完成
  48.  
  49. cf.channel().closeFuture().sync(); // 异步等待关闭连接channel
  50. System.out.println("closed.."); // 关闭完成
  51. } finally {
  52. group.shutdownGracefully().sync(); // 释放线程池资源
  53. }
  54. }
  55.  
  56. public static void main(String[] args) throws Exception {
  57. new EchoClient("127.0.0.1", 65535).start(); // 连接127.0.0.1/65535,并启动
  58. }
  59. }

  连接成功后,具体的通信代码

  1. package com.gerry.netty.client;
  2.  
  3. import java.nio.charset.Charset;
  4.  
  5. import io.netty.buffer.ByteBuf;
  6. import io.netty.buffer.ByteBufUtil;
  7. import io.netty.buffer.Unpooled;
  8. import io.netty.channel.ChannelHandlerContext;
  9. import io.netty.channel.SimpleChannelInboundHandler;
  10. import io.netty.util.CharsetUtil;
  11.  
  12. public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
  13.  
  14. @Override
  15. public void channelActive(ChannelHandlerContext ctx) throws Exception {
  16. System.out.println("client channelActive..");
  17. ctx.writeAndFlush(Unpooled.copiedBuffer("Netty rocks!", CharsetUtil.UTF_8)); // 必须有flush
  18.  
  19. // 必须存在flush
  20. // ctx.write(Unpooled.copiedBuffer("Netty rocks!", CharsetUtil.UTF_8));
  21. // ctx.flush();
  22. }
  23.  
  24. @Override
  25. protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
  26. System.out.println("client channelRead..");
  27. ByteBuf buf = msg.readBytes(msg.readableBytes());
  28. System.out.println("Client received:" + ByteBufUtil.hexDump(buf) + "; The value is:" + buf.toString(Charset.forName("utf-8")));
  29. //ctx.channel().close().sync();// client关闭channel连接
  30. }
  31.  
  32. @Override
  33. public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
  34. cause.printStackTrace();
  35. ctx.close();
  36. }
  37.  
  38. }

三、结果

  先运行server,在运行client即可。

[Netty] - Netty入门(最简单的Netty客户端/服务器程序)的更多相关文章

  1. [转]Netty入门(最简单的Netty客户端/服务器程序)

    Java中的NIO是一种解决阻塞式IO问题的基本技术,但是NIO的编写对java程序员是有比较高的要求的.那么Netty就是一种简化操作的一个成熟的网络IO编程框架.这里简单介绍一个程序,代码是< ...

  2. Netty快速入门(06)Netty介绍

    前面简单的介绍了Java I/O 和NIO,写了示例程序. Java I/O是阻塞的,为了让它支持多个并发,就要针对每个链接启动线程,这种方式的结果就是在海量链接的情况下,会创建海量的线程,就算用线程 ...

  3. Linux下select的用法--实现一个简单的回射服务器程序

    1.先看man手册 SYNOPSIS       /* According to POSIX.1-2001 */       #include <sys/select.h>       / ...

  4. 【转】C# client 与java netty 服务端的简单通信,客户端采用Unity

    http://blog.csdn.net/wilsonke/article/details/24721057 近日根据官方提供的通信例子自己写了一个关于Unity(C#)和后台通信的类,拿出来和大家分 ...

  5. 简单的TCPIP 客户端 服务器

    // soClient.cpp : Defines the entry point for the console application. // #include "stdafx.h&qu ...

  6. 最简单的回射客户/服务器程序、time_wait 状态

    下面通过最简单的客户端/服务器程序的实例来学习socket API. echoser.c 程序的功能是从客户端读取字符然后直接回射回去.  C++ Code  1 2 3 4 5 6 7 8 9 10 ...

  7. Netty学习笔记(六) 简单的聊天室功能之WebSocket客户端开发实例

    在之前的Netty相关学习笔记中,学习了如何去实现聊天室的服务段,这里我们来实现聊天室的客户端,聊天室的客户端使用的是Html5和WebSocket实现,下面我们继续学习. 创建客户端 接着第五个笔记 ...

  8. 关于Netty的入门使用

    Netty介绍: Netty是一个提供异步事件驱动的网络应用框架,用以快速开发高性能.高可靠性的网络服务器和客户端程序. 换句话说,Netty是一个NIO框架,使用它可以简单快速地开发网络应用程序,比 ...

  9. Netty学习笔记(四) 简单的聊天室功能之服务端开发

    前面三个章节,我们使用了Netty实现了DISCARD丢弃服务和回复以及自定义编码解码,这篇博客,我们要用Netty实现简单的聊天室功能. Ps: 突然想起来大学里面有个课程实训,给予UDP还是TCP ...

随机推荐

  1. Maven的安装环境配置

    一.Maven的安装 二.Maven的配置 Settings.xml可以用来定义本地仓库.远程仓库.联网代理 Settings.xml文件可以存在两个地方: 1.多用户情况 conf目录下 2.单用户 ...

  2. 弹出式菜单(下拉菜单)实现——PopupMenu

    PopupMenu代表弹出式菜单,它会在指定组件上弹出PopupMenu,默认情况下,PopupMenu会显示在该组件的下方或上方.PopupMenu可增加多个菜单项,并可为菜单项增加子菜单. 使用P ...

  3. 解析xml的问题未解决

    工作上需要解析xml,目前的逻辑是:解析xml到对象中,然后对象再插入数据库.但这存在内存溢出的风险. 今天做的另外一件事是将循环用到工作上,暂时还没有测试,是否能保证程序的重启.有待观察 ##### ...

  4. C++指针与const

    在C++中,const修饰符一般用于修饰常量.常量在定义的时候必须初始化,而且值一旦定义之后就不能修改,这样就能保证常量的值在程序运行过程中不会发生变换. 1.指向const对象的指针 指向const ...

  5. jQuery初始化

    jQuery 初始化的理解 var jQuery = function( selector, context ) { // The jQuery object is actually just the ...

  6. PHP mysqli连接MySQL数据库

    1. 开启PHP的API支持 (1)首先修改您的php.ini的配置文件.查找下面的语句:;extension=php_mysqli.dll将其修改为:extension=php_mysqli.dll ...

  7. js dorado

    1.dorado http://bsdn.org/projects/dorado7/deploy/sample-center/com.bstek.dorado.sample.Main.d#40350

  8. Delphi基本图像处理方法汇总

    这篇文章主要介绍了Delphi基本图像处理方法,实例汇总了Delphi操作图像实现浮雕.反色.模糊.翻转等常用效果的方法,非常具有实用价值,需要的朋友可以参考下   本文实例汇总了Delphi基本图像 ...

  9. ASP.NET速度优化

    用过ASP.NET的人都知道吧,页面首次打开很慢,本来网站第一次启动就慢,但别的页面如果没有访问过的第一次访问也会慢. 原因:asp.net程序第一次运行需要验证数字签名,这个验证需要远程连接微软服务 ...

  10. 小试 Ninja

    Ninja 是最近冒出来的一个 build system,它很像 make,然而效率更高,对大项目支持更好.当然我用 Ninja 和效率无关(我又没有那种有几百个中间目标的 C++ 项目要 build ...