我应该如何使用 AsynchronousServerSocketChannel 来接受连接?
我想使用 Java 7 和 NIO 2 编写一个异步服务器。
但是我应该如何使用 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();
}
}
}
I would like to write an asynchronous server using Java 7 and NIO 2.
But how should I use AsynchronousServerSocketChannel
?
E.g. if I start with:
final AsynchronousServerSocketChannel server =
AsynchronousServerSocketChannel.open().bind(
new InetSocketAddress(port));
Then when I do server.accept()
, the program terminates because that call is asynchronous. And if I put that code in an infinite loop, an AcceptPendingException
is thrown.
Any suggestions on how to write a simple asynchronous server using AsynchronousServerSocketChannel
?
Here is my full example (similar to the example in the 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();
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您走在正确的轨道上,从已完成的回调中调用accept()以接受更多连接应该可行。
防止线程终止的一个简单(但丑陋)的方法就是简单地循环,直到线程被中断。
更简洁的方法是使用 AsynchronousChannelGroup。例如:
您可以调整线程的处理方式,请参阅 AsynchronousChannelGroup API 文档 了解更多信息。
You are on the right track, calling accept() from the completed callback in order to accept more connections should work.
A simple (but ugly) way to prevent the thread from terminating is simply to loop until the thread is interrupted.
A cleaner way is to use
AsynchronousChannelGroup
. For instance:You can tune how threads are handled, see the AsynchronousChannelGroup API docs for more information.
如果您在同一个线程中还有其他事情要做,那么使用异步接受会很有用。在你的情况下,你没有做其他事情,所以我会使用
Using asynchronous accept is useful if you have something else to do in the same thread. In you case, you are not doing something else so I would use
另一种选择是让您的 main 方法在返回之前等待信号。然后,如果您有某种外部关闭命令,您只需通知该信号,主线程就会关闭。
Another alternative is to have your main method wait on a signal before returning. Then if you have some kind of external shutdown command, you just notify the signal and the main thread shuts down.
使用倒计时锁存器,如下例所示
Use count down latch like the following example