1. server

1 public class Server {
2
3 public static void main(String[] args) throws Exception {
4 System.out.println("Server is starting...");
5 //1 创建线两个程组
6 EventLoopGroup bossGroup = new NioEventLoopGroup(); //一个是用于处理服务器端接收客户端连接的
7 EventLoopGroup workGroup = new NioEventLoopGroup(); //一个是进行网络通信的(网络读写的)
8
9 //2 创建辅助工具类,用于服务器通道的一系列配置
10 ServerBootstrap b = new ServerBootstrap();
11 b.group(bossGroup, workGroup) //绑定俩个线程组
12 .channel(NioServerSocketChannel.class) //指定NIO的模式
13 .option(ChannelOption.SO_BACKLOG, 1024) //设置tcp缓冲区
14 .option(ChannelOption.SO_SNDBUF, 32*1024) //设置发送缓冲大小
15 .option(ChannelOption.SO_RCVBUF, 32*1024) //这是接收缓冲大小
16 .option(ChannelOption.SO_KEEPALIVE, true) //保持连接
17 .childHandler(new ChannelInitializer<SocketChannel>() {//服务端就是childHandler
18 @Override
19 protected void initChannel(SocketChannel socketChannel) throws Exception {
20 //3 在这里配置具体数据接收方法的处理 ChannelPipeline<<<添加到<<-ChannelHandler
21 socketChannel.pipeline().addLast(new ServerHandler());
22 }
23 });
24
25 //4 异步,进行绑定 服务端是bind,客户端是connect
26 ChannelFuture channelFuture = b.bind(8765).sync();
27 //5 等待关闭
28 channelFuture.channel().closeFuture().sync(); // 阻塞用, 等价于Thread.sleep(Integer.MAX_VALUE)
29
30 bossGroup.shutdownGracefully();
31 workGroup.shutdownGracefully();
32 }
33 }
1.2 ServerHandler

1 //服务端业务逻辑处理类
2 public class ServerHandler extends ChannelHandlerAdapter {
3 @Override
4 public void channelActive(ChannelHandlerContext ctx) throws Exception {
5 System.out.println("server channel active... ");
6 }
7
8 @Override //Object msg 服务端接收到的客户端请求的数据封装到object对象中
9 public void channelRead(ChannelHandlerContext ctx, Object msg)throws Exception {
10 ByteBuf buf = (ByteBuf) msg;
11 byte[] req = new byte[buf.readableBytes()];
12 buf.readBytes(req);//先读到字节数组中
13 String body = new String(req, "utf-8");
14 System.out.println("Server接收到客户端请求:"+body);
15 String response = "Hi Client, I am Server! you send " + body+"to me???" ;
16 //Unpooled.copiedBuffer(response.getBytes()将string-->byte[]--->ByteBuf
17 ctx.writeAndFlush(Unpooled.copiedBuffer(response.getBytes()));
18 //.addListener(ChannelFutureListener.CLOSE);
19 }
20
21 @Override
22 public void channelReadComplete(ChannelHandlerContext ctx)throws Exception {
23 System.out.println("读完了");
24 ctx.flush();
25 }
26
27 @Override
28 public void exceptionCaught(ChannelHandlerContext ctx, Throwable t)throws Exception {
29 ctx.close();
30 }
31
32 }
2. client

1 public class Client {
2 public static void main(String[] args) throws Exception{
3 System.out.println("Client is Starting...");
4 EventLoopGroup group = new NioEventLoopGroup();//客户端一个线程组,发送请求即可
5 Bootstrap b = new Bootstrap(); //辅助类, 服务端为ServerBootstrap
6 b.group(group)
7 .channel(NioSocketChannel.class)
8 .handler(new ChannelInitializer<SocketChannel>() {//服务端为childHandler(...)
9 @Override
10 protected void initChannel(SocketChannel socketChannel) throws Exception {
11 socketChannel.pipeline().addLast(new ClientHandler());//ChannelPipeline.addLast
12 }
13 });
14
15 ChannelFuture channelFuture = b.connect("127.0.0.1", 8765).sync();
16 //发送消息
17 Thread.sleep(1000);
18 channelFuture.channel().writeAndFlush(Unpooled.copiedBuffer("Client: Hi Server, I am client netty!".getBytes()));
19 channelFuture.channel().writeAndFlush(Unpooled.copiedBuffer("client request 666".getBytes()));
20 Thread.sleep(2000);
21 channelFuture.channel().writeAndFlush(Unpooled.copiedBuffer("client request 888".getBytes()));
22
23 channelFuture.channel().closeFuture().sync();//阻塞
24 group.shutdownGracefully();
25 }
26 }
3. ClientHandler

1 //客户端业务处理类
2 public class ClientHandler extends ChannelHandlerAdapter{
3 @Override
4 public void channelActive(ChannelHandlerContext ctx) throws Exception {
5 }
6
7 @Override //Object msg 客户端接收到的服务端响应的数据封装为object对象
8 public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
9 try {
10 ByteBuf buf = (ByteBuf) msg;
11 byte[] req = new byte[buf.readableBytes()]; //创建一个字节数组
12 buf.readBytes(req); //把数据先读到字节数组中
13 String body = new String(req, "utf-8");
14 String response = "Client: 收到服务器端的返回信息:" + body;
15 System.out.println(response);
16 } finally {
17 ReferenceCountUtil.release(msg); //服务端在writeAndFlush的时候自动释放了, 客户端没调用write方法需要手动释放
18 }
19 }
20
21 @Override
22 public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
23
24 }
25
26 @Override
27 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
28 throws Exception {
29 ctx.close();
30 }
31
32 }

1 结果: 2 Client is Starting... 3 Client: 收到服务器端的返回信息:Hi Client, I am Server! you send Client: Hi Server, I am client netty!client request 666to me??? 4 Client: 收到服务器端的返回信息:Hi Client, I am Server! you send client request 888to me??? 5 6 ------------------------------------------------------- 7 8 Server is starting... 9 server channel active... 10 Server接收到客户端请求:Client: Hi Server, I am client netty!client request 666 11 读完了 12 Server接收到客户端请求:client request 888 13 读完了
4. 如果想单次连接后得到响应,就关闭客户端,必须在server端关闭. .addListener(ChannelFutureListener.CLOSE)

1 //服务端业务逻辑处理类
2 public class ServerHandler extends ChannelHandlerAdapter {
3 @Override
4 public void channelActive(ChannelHandlerContext ctx) throws Exception {
5 System.out.println("server channel active... ");
6 }
7
8 @Override //Object msg 服务端接收到的客户端请求的数据封装到object对象中
9 public void channelRead(ChannelHandlerContext ctx, Object msg)throws Exception {
10 ByteBuf buf = (ByteBuf) msg;
11 byte[] req = new byte[buf.readableBytes()];
12 buf.readBytes(req);//先读到字节数组中
13 String body = new String(req, "utf-8");
14 System.out.println("Server接收到客户端请求:"+body);
15 String response = "Hi Client, I am Server! you send " + body+"to me???" ;
16 //Unpooled.copiedBuffer(response.getBytes()将string-->byte[]--->ByteBuf
17 ctx.writeAndFlush(Unpooled.copiedBuffer(response.getBytes()))
18 .addListener(ChannelFutureListener.CLOSE);//关闭通道必须在Server端,一次连接后就关闭
19 }
20
21 @Override
22 public void channelReadComplete(ChannelHandlerContext ctx)throws Exception {
23 System.out.println("读完了");
24 ctx.flush();
25 }
26
27 @Override
28 public void exceptionCaught(ChannelHandlerContext ctx, Throwable t)throws Exception {
29 ctx.close();
30 }
31
32 }
效果: 客户端只能收到服务器端一条响应

1 Client is Starting... 2 Client: 收到服务器端的返回信息:Hi Client, I am Server! you send Client: Hi Server, I am client netty!client request 666to me???
来源:http://www.cnblogs.com/bravolove/p/8039900.html
