Java中的NIO是一種解決阻塞式IO問題的基本技術,可是NIO的編寫對java程序員是有比較高的要求的。那麼Netty就是一種簡化操做的一個成熟的網絡IO編程框架。這裏簡單介紹一個程序,代碼是《netty in action》裏面的,不過那個裏面的實例有點問題,反正我沒有跑成功,修改後成功。直接上代碼:html
1、服務器編寫java
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 }
2、客戶端編寫bootstrap
具體的鏈接代碼服務器
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 }
3、結果框架
先運行server,在運行client便可。異步
轉載連接:http://www.cnblogs.com/liuming1992/p/4758532.htmlsocket
以上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>