4 Java I/O:AIO和NIO中的Selector( 三 )

/** * AIO服务端 * * @author xiangwang */public class AioServer {public void start() throws InterruptedException, IOException {AsynchronousServerSocketChannel channel = AsynchronousServerSocketChannel.open();if (channel.isOpen()) {// socket接受缓冲区recbuf大小channel.setOption(StandardSocketOptions.SO_RCVBUF, 4 * 1024);// 端口重用,防止进程意外终止,未释放端口,重启时失败// 因为直接杀进程,没有显式关闭套接字来释放端口,会等待一段时间后才可以重新use这个关口// 解决办法就是用SO_REUSEADDRchannel.setOption(StandardSocketOptions.SO_REUSEADDR, true);channel.bind(new InetSocketAddress(8080));} else {throw new RuntimeException("channel not opened!");}// 处理client连接channel.accept(null, new AioServerHandler(channel));System.out.println("server started");// 阻塞主进程for(;;) {TimeUnit.SECONDS.sleep(1);}}public static void main(String[] args) throws IOException, InterruptedException {AioServer server = new AioServer();server.start();}}/** * AIO服务端CompletionHandler * * @author xiangwang */public class AioServerHandler implements CompletionHandler<AsynchronousSocketChannel, Void> {private final AsynchronousServerSocketChannel serverChannel;private final CharsetDecoder decoder = Charset.defaultCharset().newDecoder();private final BufferedReader input = new BufferedReader(new InputStreamReader(System.in));public AioServerHandler(AsynchronousServerSocketChannel serverChannel) {this.serverChannel = serverChannel;}@Overridepublic void failed(Throwable exc, Void attachment) {// 处理下一次的client连接serverChannel.accept(null, this);}@Overridepublic void completed(AsynchronousSocketChannel result, Void attachment) {// 处理下一次的client连接,类似链式调用serverChannel.accept(null, this);try {// 将输入内容写到bufferString line = input.readLine();result.write(ByteBuffer.wrap(line.getBytes()));// 在操作系统中的Java本地方法native已经把数据写到了buffer中// 这里只需要一个缓冲区能接收就行了ByteBuffer buffer = ByteBuffer.allocate(1024);while (result.read(buffer).get() != -1) {buffer.flip();System.out.println("from client: " + decoder.decode(buffer).toString());if (buffer.hasRemaining()) {buffer.compact();} else {buffer.clear();}// 将输入内容写到bufferline = input.readLine();result.write(ByteBuffer.wrap(line.getBytes()));}} catch (InterruptedException | ExecutionException | IOException e) {e.printStackTrace();}}}执行测试后显示,不管是在客户端还是在服务端,读写完全是异步的 。
感谢您的大驾光临!咨询技术、产品、运营和管理相关问题,请关注后留言 。欢迎骚扰,不胜荣幸~

经验总结扩展阅读