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();
}
}
延伸:
Linux IO模式及 select、poll、epoll详解
异步非阻塞代码有循环的代码和过程。(单线程)在循环内是异步非阻塞,
在循环外看来这个循环整体是阻塞的。