先来看看三个异步方法的使用吧...
·异步accept使用方法:
·server.accept(null,new AcceptCompletionHandler());
·public void completed(AsynchronousSocketChannel result,
Object attachment) {
try {
//使用系统回调的AsynchronousSocketChannel ,这里用它读取(AsynchronousSocketChannel 里的数据。
buffer.clear();
result.read(buffer).get(100, TimeUnit.SECONDS);
buffer.flip();
System.out.println("received message:" + new String(buffer.array()));
} catch (InterruptedException | ExecutionException e) {
... ...
} catch (TimeoutException e) {
... ...
} finally {
try {
result.close();
AIOServer.server.accept(null, this);//这句很重要,让AsynchronousServerSocketChannel继续接受下一个连接。
} catch (Exception e) {
... ...
}
}
... ...
}
@Override
public void failed(Throwable exc, Object attachment) {
System.out.println("failed: " + exc);
}
}
·异步read使用方法:
1·result.read(buffer, buffer, new ReadCompletionHandler(result));
//异步read中的通信机制(通过参数):
//·第一个参数是OS进行异步读取后获取的数据。
//·第二个参数作为OS完成异步读取后,回调处理者(即第三个参数)时的传入参数。即第二个参数就是处理者的completed方法中的第二个参数。
//·第三个参数就是处理者
2·
public class ReadCompletionHandler implementsCompletionHandler<Integer, ByteBuffer>
{
private AsynchronousSocketChannel channel;
public ReadCompletionHandler(AsynchronousSocketChannel channel) {
if (this.channel == null){
this.channel = channel;
}
}
@Override
public void completed(Integer result, ByteBuffer attachment) {
//直接使用attachment,就是直接使用OS异步读取所获得的数据!!
attachment.flip();
byte[] body = new byte[attachment.remaining()];
attachment.get(body);
...
}
}
}
<pre name="code" class="java">·异步write使用方法:
channel.write(writeBuffer, writeBuffer,
new CompletionHandler<Integer, ByteBuffer>() {
//异步write中的附件与其处理器中的completed方法中的附件是对应的!!
@Override
public void completed(Integer result, ByteBuffer buffer) {
// 如果没有发送完成,继续发送
if (buffer.hasRemaining())
channel.write(buffer, buffer, this);
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
try {
channel.close();
} catch (IOException e) {
// ingnore on close
}
}
});
·ServerDemo:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.ExecutionException;
public class Server{
static AsynchronousServerSocketChannel server = null;
private static final int PORT = 7777;
public Server(){
try {
/**
* 第一步:用AsynchronousServerSocketChanne的静态方法open来生成AsynchronousServerSocketChannel实例。并且将其绑定在PORT端口上!!
*/
server = AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(PORT));
} catch (IOException e) {
System.out.println("该端口已经被绑定!!");
e.printStackTrace();
}
}
public void start(){
System.out.println("服务器已经启动监控" + PORT + "端口...");
/**
* 第二步:调用AsynchronousServerSocketChannel实例的异步accept方法监听(其实是把监听的任务抛给OS去做~)
*/
server.accept(null, new acceptCompletiondHandler());
/**
* 不用等待accept,继续做其他事!!(这就是异步的魅力~!!)
*/
while(true){
System.out.println("我在做其他事啦~~呵呵");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args){
new Server().start();
}
}
/**
* 第三步:实现异步accept方法中的Handler(实现CompletionHandler接口、重写completed方法、重写failed方法)
*
* 难点是理解这里:异步accept(附件,Handler)
* CompletionHandler<回调结果,附件>
* completed(回调结果,附件)
* 所有的附件都是指同一个附件,回调结果也是指同一个回调结果,这就是这几个API之间的通信机制!!
*
*/
class acceptCompletiondHandler implements CompletionHandler<AsynchronousSocketChannel,Object>{
@Override
public void completed(AsynchronousSocketChannel result,Object object){
ByteBuffer buffer = ByteBuffer.allocate(10);
buffer.clear();
result.read(buffer);
buffer.flip();
System.out.print("客户端发送过来的数据是: " + new String(buffer.array()));
System.out.println();
//将异步通道关闭
try {
result.close();
} catch (IOException e) {
System.out.println("关闭失败!!");
e.printStackTrace();
}
//将AsynchronousSeverSocketChannel设置为继续监听来自于其他客户端的连接!!
Server.server.accept(null, this);
}
@Override
public void failed(Throwable exc, Object attachment) {
// TODO Auto-generated method stub
}
}
·ClientDemo:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.util.concurrent.ExecutionException;
public class Client{
public static void main(String[] args) throws InterruptedException, ExecutionException{
AsynchronousSocketChannel client;
try {
client = AsynchronousSocketChannel.open();
client.connect(new InetSocketAddress("127.0.0.1",7777));
client.write((ByteBuffer.wrap("test".getBytes())));
} catch (IOException e) {
System.out.println("连接出错!!");
e.printStackTrace();
}
}
}
同理,甘卵经典的Demo要信手拈来~!!