Java NIO2 -- AIO CompletionHandler

113 篇文章 1 订阅
111 篇文章 0 订阅
package com.xiuye.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.StandardSocketOptions;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.concurrent.ExecutionException;

public class NIO2_AIO_Server2 {

	private AsynchronousServerSocketChannel serverChannel;

	class ServerCompletionHandler implements CompletionHandler<AsynchronousSocketChannel, Void>{

		private AsynchronousServerSocketChannel serverChannel;
		private ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
		private CharBuffer charBuffer;
		private CharsetDecoder decoder = Charset.defaultCharset().newDecoder();

		public ServerCompletionHandler(AsynchronousServerSocketChannel serverChannel) {
			this.serverChannel = serverChannel;
		}


		@Override
		public void completed(AsynchronousSocketChannel result, Void attachment) {

			//立即接收下一个请求,不停顿
			serverChannel.accept(null,this);
			try {
				while(result.read(buffer).get()!=-1){
					buffer.flip();
					charBuffer = decoder.decode(buffer);
					String request = charBuffer.toString().trim();
					System.out.println("Client Request MSG: "+request);
					ByteBuffer outBuffer = ByteBuffer.wrap("Request Received!".getBytes());
					result.write(outBuffer).get();
					if(buffer.hasRemaining()){
						buffer.compact();
					}
					else{
						buffer.clear();
					}
				}
			} catch (InterruptedException | ExecutionException e) {
				e.printStackTrace();
			} catch (CharacterCodingException e) {
				e.printStackTrace();
			}
			finally{
				try {
					result.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

		}

		@Override
		public void failed(Throwable exc, Void attachment) {
			//立即接收下一个请求,不停顿
			serverChannel.accept(null,this);
			throw new RuntimeException("connection failed!");
		}

	}

	public void init() throws IOException{
		this.serverChannel = AsynchronousServerSocketChannel.open();
		if(serverChannel.isOpen()){
			serverChannel.setOption(StandardSocketOptions.SO_RCVBUF, 4*1024);
			serverChannel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
			serverChannel.bind(new InetSocketAddress(8080));
		}else{
			throw new RuntimeException("Channel not opened!");
		}
	}

	public void start() throws InterruptedException{
		System.out.println("Wait for Client ...");
		this.serverChannel.accept(null,new ServerCompletionHandler(serverChannel));
		while(true){
			Thread.sleep(5000);
		}
	}


	public static void main(String[] args) throws IOException, InterruptedException{

		NIO2_AIO_Server2 server = new NIO2_AIO_Server2();

		server.init();
		server.start();

	}

}

package com.xiuye.nio;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.StandardSocketOptions;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.concurrent.ExecutionException;

public class NIO2_AIO_Client2 {

	class ClientCompletionHandler implements CompletionHandler<Void, Void>{

		private AsynchronousSocketChannel channel;
		private CharBuffer charBufferr = null;
		private CharsetDecoder decoder = Charset.defaultCharset().newDecoder();
		private BufferedReader clientInput = new BufferedReader(new InputStreamReader(System.in));

		public ClientCompletionHandler(AsynchronousSocketChannel channel) {
			this.channel = channel;
		}


		@Override
		public void completed(Void result, Void attachment) {

			System.out.println("Input Client Reuest:");
			String request;
			try {
				request = clientInput.readLine();
				channel.write(ByteBuffer.wrap(request.getBytes()));
				ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
				while(channel.read(buffer).get() != -1){
					buffer.flip();
					charBufferr = decoder.decode(buffer);
					System.out.println(charBufferr.toString());
					if(buffer.hasRemaining()){
						buffer.compact();
					}
					else{
						buffer.clear();
					}
					request = clientInput.readLine();
					channel.write(ByteBuffer.wrap(request.getBytes())).get();
				}
			} catch (IOException e) {
				e.printStackTrace();
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (ExecutionException e) {
				e.printStackTrace();
			}
			finally {
				try {
					channel.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}


		}

		@Override
		public void failed(Throwable exc, Void attachment) {
			throw  new  RuntimeException("channel not opened!");
		}

	}

	public void start() throws IOException, InterruptedException{
		AsynchronousSocketChannel channel = AsynchronousSocketChannel.open();
		if(channel.isOpen()){
			channel.setOption(StandardSocketOptions.SO_RCVBUF, 128*1024);
			channel.setOption(StandardSocketOptions.SO_SNDBUF, 128*1024);
			channel.setOption(StandardSocketOptions.SO_KEEPALIVE,true);
			channel.connect(new InetSocketAddress("127.0.0.1",8080),null,new ClientCompletionHandler(channel));
			while(true){
				Thread.sleep(5000);
			}
		}
		else{
			throw new RuntimeException("Channel not opened!");
		}
	}

	public static void main(String[] args) throws IOException, InterruptedException{
		NIO2_AIO_Client2 client = new NIO2_AIO_Client2();
		client.start();
	}

}

延伸:

IOCP 百度百科

Linux IO模式及 select、poll、epoll详解

IOCP模型与网络编程

对异步的尝试

异步非阻塞代码有循环的代码和过程。(单线程)在循环内是异步非阻塞,
在循环外看来这个循环整体是阻塞的。



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值