首页 > 代码库 > Nio学习4——EchoServer在Io,Nio,Nio.2中的实现
Nio学习4——EchoServer在Io,Nio,Nio.2中的实现
阻塞IO实现:
public class PlainEchoServer { public void serve(int port) throws IOException { final ServerSocket socket = new ServerSocket(port); try { while (true) { final Socket clientSocket = socket.accept(); System.out.println("Accepted connection from " + clientSocket); new Thread(new Runnable() { @Override public void run() { try { BufferedReader reader = new BufferedReader( new InputStreamReader( clientSocket.getInputStream())); PrintWriter writer = new PrintWriter( clientSocket.getOutputStream(), true); while (true) { writer.println(reader.readLine()); writer.flush(); } } catch (IOException e) { e.printStackTrace(); try { clientSocket.close(); } catch (IOException ex) { // ignore on close } } } }).start(); } } catch (IOException e) { e.printStackTrace(); } } }
非阻塞IO(NIO)实现:
public class PlainNioEchoServer { public void serve(int port) throws IOException { System.out.println("Listening for connections on port " + port); ServerSocketChannel serverChannel = ServerSocketChannel.open(); ServerSocket ss = serverChannel.socket(); InetSocketAddress address = new InetSocketAddress(port); ss.bind(address); serverChannel.configureBlocking(false); Selector selector = Selector.open(); serverChannel.register(selector, SelectionKey.OP_ACCEPT); while (true) { try { selector.select(); } catch (IOException ex) { ex.printStackTrace(); // handle in a proper way break; } Set readyKeys = selector.selectedKeys(); Iterator iterator = readyKeys.iterator(); while (iterator.hasNext()) { SelectionKey key = (SelectionKey) iterator.next(); iterator.remove(); try { if (key.isAcceptable()) { ServerSocketChannel server = (ServerSocketChannel) key .channel(); SocketChannel client = server.accept(); System.out .println("Accepted connection from " + client); client.configureBlocking(false); client.register(selector, SelectionKey.OP_WRITE | SelectionKey.OP_READ, ByteBuffer.allocate(100)); } if (key.isReadable()) { SocketChannel client = (SocketChannel) key.channel(); ByteBuffer output = (ByteBuffer) key.attachment(); client.read(output); } if (key.isWritable()) { SocketChannel client = (SocketChannel) key.channel(); ByteBuffer output = (ByteBuffer) key.attachment(); output.flip(); client.write(output); output.compact(); } } catch (IOException ex) { key.cancel(); try { key.channel().close(); } catch (IOException cex) { } } } } } }异步IO(NIO.2)实现:
public class PlainNio2EchoServer { public void serve(int port) throws IOException { System.out.println("Listening for connections on port " + port); final AsynchronousServerSocketChannel serverChannel = AsynchronousServerSocketChannel .open(); InetSocketAddress address = new InetSocketAddress(port); serverChannel.bind(address); final CountDownLatch latch = new CountDownLatch(1); serverChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() { @Override public void completed( final AsynchronousSocketChannel channel, Object attachment) { serverChannel.accept(null, this); ByteBuffer buffer = ByteBuffer.allocate(100); channel.read(buffer, buffer, new EchoCompletionHandler( channel)); } @Override public void failed(Throwable throwable, Object attachment) { try { serverChannel.close(); } catch (IOException e) { // ingnore on close } finally { latch.countDown(); } } }); try { latch.await(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } private final class EchoCompletionHandler implements CompletionHandler<Integer, ByteBuffer> { private final AsynchronousSocketChannel channel; EchoCompletionHandler(AsynchronousSocketChannel channel) { this.channel = channel; } @Override public void completed(Integer result, ByteBuffer buffer) { buffer.flip(); channel.write(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() { @Override public void completed(Integer result, ByteBuffer buffer) { if (buffer.hasRemaining()) { channel.write(buffer, buffer, this); } else { buffer.compact(); channel.read(buffer, buffer, EchoCompletionHandler.this); } } @Override public void failed(Throwable exc, ByteBuffer attachment) { try { channel.close(); } catch (IOException e) { // ingnore on close } } }); } @Override public void failed(Throwable exc, ByteBuffer attachment) { try { channel.close(); } catch (IOException e) { // ingnore on close } } } }
At first glance, it may look like more code than what you had when using the previous NIO
implementation. But notice that NIO.2 handles threading and the creation of the so-called
event loop for you. This approach simplifies the code needed to build a multithreaded NIO
application, even though it may not seem to be the case in this example. As the complexity of
the application increases, the gains become more evident because you’ll be producing cleaner
code.
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。