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即可。

转载链接:http://www.cnblogs.com/liuming1992/p/4758532.html

以上netty使用的版本

<!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.6.Final</version>
</dependency>

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

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

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

  2. Netty入门(三)之web服务器

    Netty入门(三)之web服务器 阅读前请参考 Netty入门(一)之webSocket聊天室 Netty入门(二)之PC聊天室 有了前两篇的使用基础,学习本文也很简单!只需要在前两文的基础上稍微改 ...

  3. Netty入门1之----认识Netty

      Netty 什么是Netty? Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架. Netty 是一个广泛使用的 Java ...

  4. Netty入门一:何为Netty

    先了解java的网络编程 Netty为何支持高并发 netty是基于java的nio非阻塞通信,而原始的阻塞通信无法满足高并发.下面我们通过两幅图来简要说明 BIO: 这种模式下一个线程处理一个连接, ...

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

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

  6. Netty入门系列(1) --使用Netty搭建服务端和客户端

    引言 前面我们介绍了网络一些基本的概念,虽然说这些很难吧,但是至少要做到理解吧.有了之前的基础,我们来正式揭开Netty这神秘的面纱就会简单很多. 服务端 public class PrintServ ...

  7. netty入门实现简单的echo程序

    最近看以往在程序中编写的代码,发现有一个功能是使用socket通讯来实现的,而那个时候使用的是基于bio的阻塞io来实现的,最近在看netty,发现可以使用netty来使用nio的方式来实现,此博客记 ...

  8. Netty入门系列(2) --使用Netty解决粘包和拆包问题

    前言 上一篇我们介绍了如果使用Netty来开发一个简单的服务端和客户端,接下来我们来讨论如何使用解码器来解决TCP的粘包和拆包问题 TCP为什么会粘包/拆包 我们知道,TCP是以一种流的方式来进行网络 ...

  9. Netty入门系列(3) --使用Netty进行编解码的操作

    前言 何为编解码,通俗的来说,我们需要将一串文本信息从A发送到B并且将这段文本进行加工处理,如:A将信息文本信息编码为2进制信息进行传输.B接受到的消息是一串2进制信息,需要将其解码为文本信息才能正常 ...

随机推荐

  1. 如何取消IDEA的自动删除行尾空格?

    使用IDEA,添加注释的时候敲空格,总是会把行尾空格删除导致代码跑到注释行,很不爽~~ 取消这个不爽的功能:File--Settings--Editor--General--Other--Strip ...

  2. 前端移动端开发总结(Vue)

    上下固定,中间滚动布局(FLEX) <div id="app"> <div class="header"></div> &l ...

  3. 【前端优化】图片延迟加载Lazy-loading的原理与简单实现

    1.什么是lazy-loading 图片"懒加载" 为img标签src设置统一的图片链接,而将真实链接地址装在自定义属性中. 所以开始时候图片是不会加载的,我们将满足条件的图片的s ...

  4. spring security学习总结

    这几天一直在学习spring security的相关知识.逛各大论坛,看相关api与教学视频,获益良多! 简介 Spring Security是为基于Spring的企业应用系统提供声明式的安全访问控制 ...

  5. Delphi 窗体函数GetWindowRect 取窗口矩形坐标

    GetWindowRect,用于取窗口矩形坐标.返回值类型:布尔型(LongBool).执行成功返回真(True),否则返回假(False);参数1类型:整数型(HWND),目标窗口的窗口句柄;参数2 ...

  6. 「NOI2016」循环之美(小性质+min_25筛)

    传送门. 题解 感觉这题最难的是第一个结论. x/y首先要互质,然后如果在10进制是纯循环小数,不难想到y不是2.5的倍数就好了. 因为十进制下除以2和5是除得尽的. 必然会多出来的什么东西. 如果是 ...

  7. rails问题检查

    在做rails postgresql过程中,使用同事的老代码,然后坐到db:migrate时发现总是报错 这种错误是无法在百度或者google搞定的,需要去进入到底层查看 所以需要进入相关文件看,到d ...

  8. Spring源码剖析3:Spring IOC容器的加载过程

    本文转自五月的仓颉 https://www.cnblogs.com/xrq730 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https ...

  9. 22、继续javascript,左边选中的跳到右边

    1. <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title& ...

  10. 戏说 .NET GDI+系列学习教程(三、Graphics类的应用_自定义控件--主要用于画面拖拽效果)

    如题,需求:在某个图片上用户可以手动指定位置. 如下: 中心思想:仿照Visual Studio工具中的控件的做法 如何仿照呢? 1.自定义的控件类继承System.Windows.Forms.Con ...