Java的網(wǎng)絡(luò)編程有兩種主要的技術(shù):Java NIO 和 Java Netty。
Java NIO即Java Non-blocking I/O, 可以實(shí)現(xiàn)同步和異步兩種IO操作。它提供了Channel、Buffer、Selector等實(shí)現(xiàn),使得Java程序可以實(shí)現(xiàn)高效的I/O操作,避免阻塞等待發(fā)生。Java NIO的代碼量更少,效率更高。例如:
public class NIOServer { public static void main(String[] args) throws IOException { ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.socket().bind(new InetSocketAddress(9999)); serverSocketChannel.configureBlocking(false); Selector selector = Selector.open(); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); while (true) { if (selector.select(5000) == 0) { System.out.println("5秒鐘內(nèi)沒有客戶端連接"); } else { SetselectionKeys = selector.selectedKeys(); Iterator keyIterator = selectionKeys.iterator(); while (keyIterator.hasNext()) { SelectionKey selectionKey = keyIterator.next(); if (selectionKey.isAcceptable()) { SocketChannel socketChannel = serverSocketChannel.accept(); socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024)); System.out.println("連接成功"); } if (selectionKey.isReadable()) { SocketChannel socketChannel = (SocketChannel) selectionKey.channel(); ByteBuffer byteBuffer = (ByteBuffer) selectionKey.attachment(); socketChannel.read(byteBuffer); System.out.println(new String(byteBuffer.array())); } keyIterator.remove(); } } } } }
Java Netty是一個(gè)異步的、事件驅(qū)動(dòng)的網(wǎng)絡(luò)應(yīng)用框架。它是網(wǎng)絡(luò)編程的高級(jí)模式,把網(wǎng)絡(luò)操作都抽象成一組事件,然后交由事件驅(qū)動(dòng)的程序處理。Netty更高級(jí),使用更方便,它的API非常友好,可以使用多種設(shè)計(jì)模式和機(jī)制,方便地實(shí)現(xiàn)自定義協(xié)議。例如:
public class NettyServer { public static void main(String[] args) throws InterruptedException { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 1024) .childOption(ChannelOption.SO_KEEPALIVE, true) .childHandler(new ChannelInitializer() { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline p = ch.pipeline(); p.addLast(new LineBasedFrameDecoder(1024)); p.addLast(new StringDecoder()); p.addLast(new ServerHandler()); } }); ChannelFuture f = serverBootstrap.bind(9999).sync(); f.channel().closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } } public class ServerHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { String body = (String) msg; System.out.println("客戶端發(fā)來的請(qǐng)求為:" + body); String response = "hello client"; response += System.getProperty("line.separator"); ctx.writeAndFlush(response.getBytes()); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { ctx.flush(); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { ctx.close(); System.err.println("發(fā)生異常:" + cause.getMessage()); } }
Java NIO和Java Netty都是Java網(wǎng)絡(luò)編程中不可缺少的部分,應(yīng)該針對(duì)實(shí)際應(yīng)用場景選擇合適的技術(shù)。