一,jdk
1,使用OIO的阻塞版本:
public class JDKOioServer { public void server(int port) throws IOException { final ServerSocket serverSocket = new ServerSocket(port); try{ for(;;){ final Socket csocket = serverSocket.accept(); System.out.println("Accepted connection from"+csocket); new Thread(new Runnable() { @Override public void run() { OutputStream out; try{ out = csocket.getOutputStream(); out.write("Hi!\r\n".getBytes(Charset.forName("UTF-8"))); out.flush(); csocket.close(); }catch (IOException e){ e.printStackTrace(); }finally { try { csocket.close(); }catch (IOException ex){ } } } }).start(); } }catch (IOException e){ e.printStackTrace(); } } }
2,使用NIO的非阻塞版本:
public class JDKNioServer { public void server(int port)throws IOException{ ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.configureBlocking(false); ServerSocket socket = serverSocketChannel.socket(); InetSocketAddress address = new InetSocketAddress(port); socket.bind(address); Selector selector = Selector.open(); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); final ByteBuffer msg = ByteBuffer.wrap("Hi\r\n".getBytes()); for(;;){ try{ selector.select(); }catch (IOException e){ e.printStackTrace(); break; } Set<SelectionKey> readyKeys = selector.selectedKeys(); Iterator<SelectionKey> iterator = readyKeys.iterator(); while(iterator.hasNext()){ SelectionKey key = iterator.next(); iterator.remove(); try{ if(key.isAcceptable()){ ServerSocketChannel server = (ServerSocketChannel) key.channel(); SocketChannel client = server.accept(); client.configureBlocking(false); client.register(selector,SelectionKey.OP_WRITE|SelectionKey.OP_READ,msg.duplicate()); System.out.println("Accepted connection from"+client); } if(key.isWritable()){ SocketChannel client = (SocketChannel) key.channel(); ByteBuffer byteBuffer = (ByteBuffer) key.attachment(); while(byteBuffer.hasRemaining()){ if(client.write(byteBuffer)==0){ break; } } client.close(); } }catch (IOException ex){ key.cancel(); try { key.channel().close(); }catch (IOException cex){ } } } } } }jdk的阻塞和非阻塞版本代码完全不同.
二,Netty
1,阻塞版
public class NettyOioServer { public void server(int port)throws Exception{ final ByteBuf buf = Unpooled.unreleasableBuffer( Unpooled.copiedBuffer("Hi\r\n", Charset.forName("UTF-8")) ); EventLoopGroup group = new OioEventLoopGroup(); try{ ServerBootstrap b = new ServerBootstrap(); b.group(group) .channel(OioServerSocketChannel.class) .localAddress(new InetSocketAddress(port)) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { socketChannel.pipeline().addLast( new ChannelInboundHandlerAdapter(){ @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { ctx.writeAndFlush(buf.duplicate()).addListener(ChannelFutureListener.CLOSE); } } ); } }); ChannelFuture f = b.bind().sync(); f.channel().closeFuture().sync(); }finally { group.shutdownGracefully().sync(); } } }2,非阻塞版
public class NettyNioServer { public void server(int port)throws Exception{ final ByteBuf buf = Unpooled.unreleasableBuffer( Unpooled.copiedBuffer("Hi\r\n", Charset.forName("UTF-8")) ); EventLoopGroup group = new NioEventLoopGroup(); //1 try{ ServerBootstrap b = new ServerBootstrap(); b.group(group) .channel(NioServerSocketChannel.class) //2 .localAddress(new InetSocketAddress(port)) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { socketChannel.pipeline().addLast( new ChannelInboundHandlerAdapter(){ @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { ctx.writeAndFlush(buf.duplicate()).addListener(ChannelFutureListener.CLOSE); } } ); } }); ChannelFuture f = b.bind().sync(); f.channel().closeFuture().sync(); }finally { group.shutdownGracefully().sync(); } } }阻塞版本和非阻塞版本只有1,2两处不一样.
与jdk相比,netty为没中传输实现都暴露了相同的API.无论选哪一种实现,代码几乎不受影响.