package com.youkeda.test.aio.server;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
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.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
/**A
* AIO 服务端
*/
public class AIOServer implements Runnable {
// 端口号
private int port;
private int threadSize;
// 异步
protected AsynchronousChannelGroup asynchronousChannelGroup;
protected AsynchronousServerSocketChannel serverChannel;
public AIOServer(int port, int threadSize) {
this.port = port;
this.threadSize = threadSize;
init();
}
// 服务端启动过程初始化
private void init() {
try {
asynchronousChannelGroup = AsynchronousChannelGroup
.withCachedThreadPool(Executors.newCachedThreadPool(), 10);
serverChannel = AsynchronousServerSocketChannel.open(asynchronousChannelGroup);
serverChannel.bind(new InetSocketAddress(port));
System.out.println("listening on port: " + port);
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
try {
if (serverChannel == null) {
return;
}
// 收到客户端连接后,回调匿名类
serverChannel.accept(this, new CompletionHandler<AsynchronousSocketChannel, AIOServer>() {
final ByteBuffer echoBuffer = ByteBuffer.allocateDirect(1024);
public void completed(AsynchronousSocketChannel result, AIOServer attachment) {
try {
echoBuffer.clear();
// 客户端输入的数据读取完毕,封装为 ByteBuffer 对象
result.read(echoBuffer).get();
echoBuffer.flip();
// 输入的数据解码组装为字符串
String clientMsg = Charset.forName("gbk").decode(echoBuffer).toString();
System.out.println("received : " + clientMsg);
String msg = "server return msg-" + Math.random();
System.out.println("server send data: " + msg);
result.write(ByteBuffer.wrap(msg.getBytes()));
} catch (Exception e) {
e.printStackTrace();
} finally {
attachment.serverChannel.accept(attachment, this);// 监听新的请求,递归调用。
}
}
public void failed(Throwable exc, AIOServer attachment) {
System.out.println("received failed");
exc.printStackTrace();
attachment.serverChannel.accept(attachment, this);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
private static int getPort() {
Double port = (Math.random() + 1) * 10000;
return port.intValue();
}
public static void main(String[] args) throws IOException {
Thread aioServer = new Thread(new AIOServer(getPort(), 3));
aioServer.start();
}
}
AIO
最新推荐文章于 2022-06-04 19:12:56 发布