《Netty 5用戶指南》http://ifeve.com/netty5-user-guide/
Netty是一個NIO框架,使用它可以簡單快速地開發網絡應用程序,比如客戶端和服務端的協議。
Netty大大簡化了網絡程序的開發過程比如TCP和UDP的 Socket的開發。
1、Client.java
1 package com.yxq.test; 2 import io.netty.bootstrap.Bootstrap; 3 import io.netty.buffer.Unpooled; 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 public class Client { 12 13 public static void main(String[] args) throws Exception { 14 15 EventLoopGroup workgroup = new NioEventLoopGroup(); 16 Bootstrap b = new Bootstrap(); 17 b.group(workgroup) 18 .channel(NioSocketChannel.class) 19 .handler(new ChannelInitializer<SocketChannel>() { 20 @Override 21 protected void initChannel(SocketChannel sc) throws Exception { 22 sc.pipeline().addLast(new ClientHandler()); 23 } 24 }); 25 26 ChannelFuture cf1 = b.connect("127.0.0.1", 8765).sync(); 27 28 //buf 29 cf1.channel().writeAndFlush(Unpooled.copiedBuffer("777".getBytes())); 30 31 cf1.channel().closeFuture().sync(); 32 workgroup.shutdownGracefully(); 33 34 } 35 }
2、ClientHandler.java
1 package com.yxq.test; 2 3 import io.netty.buffer.ByteBuf; 4 import io.netty.buffer.Unpooled; 5 import io.netty.channel.ChannelHandlerAdapter; 6 import io.netty.channel.ChannelHandlerContext; 7 import io.netty.util.ReferenceCountUtil; 8 9 public class ClientHandler extends ChannelHandlerAdapter { 10 11 @Override 12 public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 13 try { 14 //do something msg 15 ByteBuf buf = (ByteBuf)msg; 16 byte[] data = new byte[buf.readableBytes()]; 17 buf.readBytes(data); 18 String request = new String(data, "utf-8"); 19 System.out.println("Client: " + request); 20 21 22 } finally { 23 ReferenceCountUtil.release(msg); 24 } 25 } 26 27 @Override 28 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 29 cause.printStackTrace(); 30 ctx.close(); 31 } 32 }
3、Server.java
1 package com.yxq.test; 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 11 public class Server { 12 13 public static void main(String[] args) throws Exception { 14 //1 第一個線程組 是用於接收Client端連接的 15 EventLoopGroup bossGroup = new NioEventLoopGroup(); 16 //2 第二個線程組 是用於實際的業務處理操作的 17 EventLoopGroup workerGroup = new NioEventLoopGroup(); 18 19 //3 創建一個輔助類Bootstrap,就是對我們的Server進行一系列的配置 20 ServerBootstrap b = new ServerBootstrap(); 21 //把倆個工作線程組加入進來 22 b.group(bossGroup, workerGroup) 23 //我要指定使用NioServerSocketChannel這種類型的通道 24 .channel(NioServerSocketChannel.class) 25 //一定要使用 childHandler 去綁定具體的 事件處理器 26 .childHandler(new ChannelInitializer<SocketChannel>() { 27 @Override 28 protected void initChannel(SocketChannel sc) throws Exception { 29 sc.pipeline().addLast(new ServerHandler()); 30 } 31 }); 32 33 //綁定指定的端口 進行監聽 34 ChannelFuture f = b.bind(8765).sync(); 35 36 //Thread.sleep(1000000); 37 f.channel().closeFuture().sync(); 38 39 bossGroup.shutdownGracefully(); 40 workerGroup.shutdownGracefully(); 41 42 43 44 } 45 46 }
4、ServerHandler.java
1 package com.yxq.test; 2 3 import io.netty.buffer.ByteBuf; 4 import io.netty.buffer.Unpooled; 5 import io.netty.channel.ChannelFuture; 6 import io.netty.channel.ChannelFutureListener; 7 import io.netty.channel.ChannelHandlerAdapter; 8 import io.netty.channel.ChannelHandlerContext; 9 import io.netty.util.ReferenceCountUtil; 10 11 public class ServerHandler extends ChannelHandlerAdapter { 12 13 @Override 14 public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 15 16 //do something msg 17 ByteBuf buf = (ByteBuf)msg; 18 byte[] data = new byte[buf.readableBytes()]; 19 buf.readBytes(data); 20 String request = new String(data, "utf-8"); 21 System.out.println("Server: " + request); 22 //寫給客戶端 23 String response = "我是反饋的信息"; 24 ctx.writeAndFlush(Unpooled.copiedBuffer("888".getBytes())); 25 //.addListener(ChannelFutureListener.CLOSE); 26 27 28 } 29 30 @Override 31 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 32 cause.printStackTrace(); 33 ctx.close(); 34 } 35 36 }
打印:
先啟server端,再啟client端