代码:
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;
import java.util.concurrent.TimeoutException;
public class AIOServer {
public final static int PORT = 9888;
private AsynchronousServerSocketChannel server;
public AIOServer() throws IOException {
System.out.println("APP Start, ThreadID = "+Thread.currentThread().getId());
server = AsynchronousServerSocketChannel.open().bind(
new InetSocketAddress(PORT)
);
}
public void startWithCompletionHandler() throws InterruptedException, ExecutionException,
TimeoutException {
System.out.println("Server Listenning ..., Port = " + PORT);
//注册事件和事件完成后的处理器
server.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() {
final ByteBuffer buffer = ByteBuffer.allocate(1024);
public void completed(AsynchronousSocketChannel socketChannel, Object attachment) {
System.out.println("Accpet Completed, ThreadID = "+Thread.currentThread().getId()+", socketChannel = "+socketChannel.hashCode());
CompletionHandler<Integer,ByteBuffer> handler=new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer readLen, ByteBuffer attachment) {
System.out.println("Read Completed, ThreadID = "+Thread.currentThread().getId()+", socketChannel = "+socketChannel.hashCode());
if (readLen < 0){
System.out.println("Read Error!"); //经测试,如果在读取的过程中连接断开,readLen会小于0
return;
}
attachment.flip();
System.out.println("Read Success, Data = "+new String(attachment.array()));
socketChannel.read(buffer, buffer, this); //执行下一次read,否则本Socket只能读取一次
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
System.out.println("Read Failed!");
}
};
socketChannel.read(buffer, buffer, handler);
server.accept(null, this); //执行下一次Accept,否则本Socket服务器只能连接一次
}
@Override
public void failed(Throwable exc, Object attachment) {
System.out.println("Accept Failed : " + exc);
}
});
// 主线程继续自己的行为
while(true) {
Thread.sleep(10);
}
}
public static void main(String[] args) throws Exception {
new AIOServer().startWithCompletionHandler();
}
}
运行效果:
注:图中Read Error 是客户端断开TCP连接时的输出。