AIO通讯
- 异步非阻塞的通讯方式,就是不需要等待一方的数据操作完成,会自动执行回调函数处理的读写操作
- 主要类
– AsynchronousServerSocketChannel 服务器接收请求通道
bind 绑定在某一端口 accept 接收客户端请求
– AsynchronousSocketChannel Socket 通讯通道
read write
– CompletionHandler 异步处理类
completed 操作完成后异步调用方法 failed 操作失败后异步调用方法
package aio;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class AioServer {
public static void main(String[] args) throws IOException {
AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open();
server.bind(new InetSocketAddress("localhost", 8001));
System.out.println("服务器在8001端口守候");
//开始等待客户端连接,一旦有连接,做26行任务
server.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() {
@Override
public void completed(AsynchronousSocketChannel channel, Object attachment) {
server.accept(null, this); //持续接收新的客户端请求
ByteBuffer buffer = ByteBuffer.allocate(1024); //准备读取空间
//开始读取客户端内容,一旦读取结束,做33行任务
channel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result_num, ByteBuffer attachment) {
attachment.flip(); //反转此Buffer
CharBuffer charBuffer = CharBuffer.allocate(1024);
CharsetDecoder decoder = Charset.defaultCharset().newDecoder();
decoder.decode(attachment,charBuffer,false);
charBuffer.flip();
String data = new String(charBuffer.array(),0, charBuffer.limit());
System.out.println("client said: " + data);
channel.write(ByteBuffer.wrap((data + " 666").getBytes())); //返回结果给客户端
try{
channel.close();
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
System.out.println("read error "+exc.getMessage());
}
});
}
@Override
public void failed(Throwable exc, Object attachment) {
System.out.print("failed: " + exc.getMessage());
}
});
while(true){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
package aio;
import java.net.InetSocketAddress;
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.UUID;
public class AioClient {
public static void main(String[] a) {
try
{
AsynchronousSocketChannel channel = AsynchronousSocketChannel.open();
//18行连接成功后,自动做20行任务
channel.connect(new InetSocketAddress("localhost", 8001), null, new CompletionHandler<Void, Void>() {
public void completed(Void result, Void attachment) {
String str = UUID.randomUUID().toString();
//24行向服务器写数据成功后,自动做28行任务
channel.write(ByteBuffer.wrap(str.getBytes()), null,
new CompletionHandler<Integer, Object>() {
@Override
public void completed(Integer result, Object attachment) {
try {
System.out.println("write " + str + ", and wait response");
//等待服务器响应
ByteBuffer buffer = ByteBuffer.allocate(1024); //准备读取空间
//开始读取服务器反馈内容,一旦读取结束,做39行任务
channel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result_num, ByteBuffer attachment) {
attachment.flip(); //反转此Buffer
CharBuffer charBuffer = CharBuffer.allocate(1024);
CharsetDecoder decoder = Charset.defaultCharset().newDecoder();
decoder.decode(attachment,charBuffer,false);
charBuffer.flip();
String data = new String(charBuffer.array(),0, charBuffer.limit());
System.out.println("server said: " + data);
try{
channel.close();
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
System.out.println("read error "+exc.getMessage());
}
});
channel.close();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void failed(Throwable exc, Object attachment) {
System.out.println("write error");
}
});
}
public void failed(Throwable exc, Void attachment) {
System.out.println("fail");
}
});
Thread.sleep(10000);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
每一个CompletionHandler 都可以定义俩个方法:completed和failed方法,当操作成功自动运行completed方法,失败自动调用failed方法