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

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

时间: 2024-10-06 08:23:05

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

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

Java中的NIO是一种解决阻塞式IO问题的基本技术,但是NIO的编写对java程序员是有比较高的要求的.那么Netty就是一种简化操作的一个成熟的网络IO编程框架.这里简单介绍一个程序,代码是<netty in action>里面的,不过那个里面的实例有点问题,反正我没有跑成功,修改后成功.直接上代码: 一.服务器编写 Server代码,监听连接 1 package com.gerry.netty.server; 2 3 import io.netty.bootstrap.ServerBoo

Unix网络编程学习笔记之第5章 TCP客户端/服务器程序示例

一. 一个简单TCP回射服务端程序 #include "unp.h" #define MAXLINE 1024 #define PORT 13 #define CONMAX 5 void err_sys(const char* s) { fprintf(stderr, "%s\n",s); exit(1); } void str_echo(int connfd) { int nbyte; char buff[MAXLINE+1]; again: while(nbyt

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

http://blog.csdn.net/wilsonke/article/details/24721057 近日根据官方提供的通信例子自己写了一个关于Unity(C#)和后台通信的类,拿出来和大家分享一下. 具体请参考: 1.java服务端用的apach.mina框架搭建.java服务端请参考:http://blog.9tech.cn/?c=site&m=article&id=548 2.C#环境:.NET framework 2.0 3.C#帮组文档,及Socket注解:http://

socket的客户端-服务器程序

客户端程序: 通过服务器返回当前的时间和日期. #include "unp.h" #include "my_err.h" int main(int argc, char** argv) { int sockfd, n; char recvline[MAXLINE + 1]; struct sockaddr_in servaddr; if (argc != 2) err_quit("usage:a.out<IPaddress>"); i

一个简单的时间获取服务器程序

程序执行流程: 1.创建TCP套接字 listenfd = Socket(AF_INET, SOCK_STREAM, 0) 2.清空sockaddr_in  servaddr结构体 bzero(&servaddr, sizeof(servaddr)) 3.填写网际套接字地址结构 我们指定IP地址为INADDR_ANY,这样要是服务器主机有多个网络接口,服务器进程就可以在任意网络接口上接受客户连接 servaddr.sin_family      = AF_INET; servaddr.sin_a

UNIX网络编程1.5一个简单的时间获取服务器程序1.6客户服务器程序索引表

#include "../lib/unpsunyj.h" #include <time.h> int main(int argc, char ** argv) { int listenfd; int connfd; sockaddr_in servaddr; char buff[MAXLINE]; time_t ticks; // TCP套接字的创建 // listenfd = Socket(AF_INET, SOCK_STREAM, 0); if ((listenfd =

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

下面通过最简单的客户端/服务器程序的实例来学习socket API. echoser.c 程序的功能是从客户端读取字符然后直接回射回去. C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 6

从入门到实战,Netty多线程篇案例集锦

从入门到实战,Netty多线程篇案例集锦 原创 2015-09-10 李林峰 InfoQ Netty案例集锦系列文章介绍 1|Netty的特点 Netty入门比较简单,主要原因有如下几点: Netty的API封装比较简单,将复杂的网络通信通过BootStrap等工具类做了二次封装,用户使用起来比较简单: Netty源码自带的Demo比较多,通过Demo可以很快入门: Netty社区资料.相关学习书籍也比较多,学习资料比较丰富. 但是很多入门之后的Netty学习者遇到了很多困惑,例如不知道在实际项

Netty之入门

在上篇<Netty之引题>中,分别对AIO,BIO,PIO,NIO进行了简单的阐述,并写了简单的demo.但是这里说的简单,我也只能呵呵了,特别是NIO.AIO(我全手打的,好麻烦).在开始netty开发TimeServer之前,先回顾下NIO进行服务端开发的步骤: 1.创建ServerSocketChannel,配置它为非阻塞: 2.绑定监听,配置TCP参数,如backlog大小: 3.创建独立的IO线程,用于轮询多路复用器Selector; 4.创建Selector,将之前创建的Serve