我有一个小型服务器设置,我正在尝试使用基于事件的连接套接字,以便在每个传入连接上调用一个处理程序。它适用于第一个连接,但在第一个连接后不接受新连接。
为了简单起见,我只是关闭了客户端连接。此外,是的,服务器在第一次连接后仍在运行,它不会终止。
以下是代码:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class ServerTest
{
static CompletionHandler<AsynchronousSocketChannel, Object> handler =
new CompletionHandler<AsynchronousSocketChannel, Object>() {
@Override
public void completed(AsynchronousSocketChannel result, Object attachment) {
System.out.println(attachment + " completed with " + result + " bytes written");
try {
result.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void failed(Throwable e, Object attachment) {
System.err.println(attachment + " failed with:");
e.printStackTrace();
}
};
public static void main(String[] args) throws Exception
{
AsynchronousChannelGroup group = AsynchronousChannelGroup.withThreadPool(Executors.newSingleThreadExecutor());
System.out.println("STARTING");
AsynchronousServerSocketChannel ssc =
AsynchronousServerSocketChannel.open(group).bind(new InetSocketAddress("localhost", 9999));
System.out.println("BOUND");
ssc.accept(ssc, handler);
group.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
}
}
答案 0 :(得分:0)
public abstract void accept(附件,CompletionHandler处理程序)
此方法启动异步操作以接受与此通道的套接字建立的连接。 handler参数是一个完成处理程序,在接受连接(或操作失败)时调用。传递给完成处理程序的结果是新连接的AsynchronousSocketChannel。
了解更多here
这意味着它初始化异步线程以接受传入连接。这也意味着它将接受第一个连接并将其转发到异步线程,然后等待更多连接。要允许更多客户端连接,您还必须在覆盖的已完成函数内部调用accept方法。
这是一个例子,
server.accept(null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
@Override
public void completed(AsynchronousSocketChannel chan, Void attachment) {
System.out.println("Incoming connection...");
server.accept(null, this); //add this
//...
应该注意,对于每个客户端,都会生成一个新的AsynchronousSocketChannel结果。话虽如此,如果你要打印出来,它会产生不同的对象。