我想用Java7和NIO2写一个异步服务器。
但是我应该如何使用AsynchronousServerSocketChannel
呢?
例如,如果我从以下内容开始:
final AsynchronousServerSocketChannel server =
AsynchronousServerSocketChannel.open().bind(
new InetSocketAddress(port));
然后,当我执行server.accept()
时,程序终止,因为该调用是异步的。如果我把代码放在无限循环中,就会抛出一个AcceptPendingException
。
关于如何使用AsynchronousServerSocketChannel
编写简单的异步服务器有什么建议吗?
下面是我的完整示例(类似于JavaDoc中的示例):
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
public class AsyncServer {
public static void main(String[] args) {
int port = 8060;
try {
final AsynchronousServerSocketChannel server =
AsynchronousServerSocketChannel.open().bind(
new InetSocketAddress(port));
System.out.println("Server listening on " + port);
server.accept("Client connection",
new CompletionHandler<AsynchronousSocketChannel, Object>() {
public void completed(AsynchronousSocketChannel ch, Object att) {
System.out.println("Accepted a connection");
// accept the next connection
server.accept("Client connection", this);
// handle this connection
//TODO handle(ch);
}
public void failed(Throwable exc, Object att) {
System.out.println("Failed to accept connection");
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}
发布于 2012-02-26 06:38:27
您在正确的轨道上,从已完成的回调中调用accept(),以便接受更多的连接。
防止线程终止的一种简单(但丑陋)的方法是简单地循环,直到线程被中断。
// yes, sleep() is evil, but sometimes I don't care
while (true) {
Thread.sleep(1000);
}
更简洁的方法是使用AsynchronousChannelGroup
。例如:
AsynchronousChannelGroup group = AsynchronousChannelGroup.withThreadPool(Executors
.newSingleThreadExecutor());
AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open(group).bind(
new InetSocketAddress(port));
// (insert server.accept() logic here)
// wait until group.shutdown()/shutdownNow(), or the thread is interrupted:
group.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
您可以调整线程的处理方式,有关更多信息,请参阅AsynchronousChannelGroup API docs。
发布于 2012-01-20 21:51:40
如果在同一线程中有其他事情要做,那么使用异步accept是很有用的。在您的情况下,您没有做其他事情,所以我将使用
while(true) {
AsynchronousSocketChannel socket = server.accept().get();
System.out.println("Accepted " + socket);
socket.close();
}
发布于 2015-04-18 20:46:22
另一种方法是让main方法在返回之前等待一个信号。然后,如果您有某种外部关闭命令,您只需通知该信号,主线程就会关闭。
private static final Object shutdownSignal = new Object();
public static void main(String[] args) {
...
synchronized (shutdownSignal) {
try {
shutdownSignal.wait();
}
catch (InterruptedException e) {
// handle it!
}
}
}
https://stackoverflow.com/questions/8940747
复制相似问题