首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用AsynchronousServerSocketChannel接受连接?

如何使用AsynchronousServerSocketChannel接受连接?
EN

Stack Overflow用户
提问于 2012-01-20 19:31:23
回答 4查看 12.4K关注 0票数 20

我想用Java7和NIO2写一个异步服务器。

但是我应该如何使用AsynchronousServerSocketChannel呢?

例如,如果我从以下内容开始:

代码语言:javascript
复制
final AsynchronousServerSocketChannel server = 
    AsynchronousServerSocketChannel.open().bind(
        new InetSocketAddress(port));

然后,当我执行server.accept()时,程序终止,因为该调用是异步的。如果我把代码放在无限循环中,就会抛出一个AcceptPendingException

关于如何使用AsynchronousServerSocketChannel编写简单的异步服务器有什么建议吗?

下面是我的完整示例(类似于JavaDoc中的示例):

代码语言:javascript
复制
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();
        }
    }
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-02-26 06:38:27

您在正确的轨道上,从已完成的回调中调用accept(),以便接受更多的连接。

防止线程终止的一种简单(但丑陋)的方法是简单地循环,直到线程被中断。

代码语言:javascript
复制
// yes, sleep() is evil, but sometimes I don't care
while (true) {
    Thread.sleep(1000);
}

更简洁的方法是使用AsynchronousChannelGroup。例如:

代码语言:javascript
复制
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

票数 16
EN

Stack Overflow用户

发布于 2012-01-20 21:51:40

如果在同一线程中有其他事情要做,那么使用异步accept是很有用的。在您的情况下,您没有做其他事情,所以我将使用

代码语言:javascript
复制
while(true) {
    AsynchronousSocketChannel socket = server.accept().get();
    System.out.println("Accepted " + socket);
    socket.close();
}
票数 4
EN

Stack Overflow用户

发布于 2015-04-18 20:46:22

另一种方法是让main方法在返回之前等待一个信号。然后,如果您有某种外部关闭命令,您只需通知该信号,主线程就会关闭。

代码语言:javascript
复制
private static final Object shutdownSignal = new Object();

public static void main(String[] args) {

    ...

    synchronized (shutdownSignal) {
        try {
            shutdownSignal.wait();
        }
        catch (InterruptedException e) {
            // handle it!
        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8940747

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档