首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使异步tcp服务器继续监听通道而不关闭通道

如何使异步tcp服务器继续监听通道而不关闭通道
EN

Stack Overflow用户
提问于 2013-03-18 03:44:28
回答 1查看 1.9K关注 0票数 1

我正在尝试制作一个能够处理来自客户端的1000+连接的服务器。这部分是学术的,部分是业余爱好项目,所以我有点想做自己的解决方案,但我面临着一个问题:当我开始侦听连接时,有人连接,TCP连接在5秒后被java关闭。我知道这是从我的5秒睡眠,但如果我删除它,它立即返回。

下面是我的服务器代码(精简版):

代码语言:javascript
复制
    final int SERVER_PORT = 9000;
    final String SERVER_IP = "10.0.0.201";

    AsynchronousChannelGroup group = null;
    try {
        group = AsynchronousChannelGroup.withThreadPool(threadPool);
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    // Create asynchronous server-socket channel bound to the default group.
    try(AsynchronousServerSocketChannel asynchronousServerSocketChannel = AsynchronousServerSocketChannel
            .open(group)) {
        if ( asynchronousServerSocketChannel.isOpen() ) {
            // Bind to local address
            asynchronousServerSocketChannel.bind(new InetSocketAddress(SERVER_IP, SERVER_PORT),
                    SERVER_SOCKET_CHANNEL_BACKLOG);
            // Display a waiting message
            System.out.println("Waiting for connections on ip:port " + SERVER_IP + ":" + SERVER_PORT);
            while (true) { // Not good?
                Future<AsynchronousSocketChannel> asynchronousSocketChannelFuture = asynchronousServerSocketChannel
                        .accept();
                try(AsynchronousSocketChannel asynchronousSocketChannel = asynchronousSocketChannelFuture.get()) {

                    final SocketAddress remoteAddress = asynchronousSocketChannel.getRemoteAddress();

                    System.out.println("Incoming connection from: " + remoteAddress);
                    final ByteBuffer incomingBuffer = ByteBuffer.allocateDirect(1024);

                    // Time to receive data.
                    asynchronousSocketChannel.read(incomingBuffer, incomingBuffer,
                            new CompletionHandler<Integer, ByteBuffer>() {

                                public void completed( Integer result, ByteBuffer buffer ) {

                                }

                                public void failed( Throwable exc, ByteBuffer buffer ) {
                                    if ( exc instanceof AsynchronousCloseException ) {
                                        // Someone closed the connection
                                        // while we where listening on it.
                                        System.out.println("We listened on the socket, but someone closed it.");
                                    }
                                }
                            });

                    try {
                        Thread.sleep(5000);
                    } catch (Exception e) {
                        System.out.println(e.toString());
                    }
                } catch (IOException | InterruptedException | ExecutionException ex) {
                    System.err.println(ex);
                }
            }
        } else {
            System.out.println("The asynchronous server-socket channel cannot be opened!");
        }
    } catch (IOException ex) {
        System.err.println(ex);
    }
}

当运行此代码并使用netcat "nc 10.0.0.201 9000“连接时,连接在5秒后从java/服务器端重置(如果解除休眠,则立即重置)。

我如何才能阻止它返回,并让它继续侦听?在解决我最初的目标时,我采取了正确的方法吗?

EN

回答 1

Stack Overflow用户

发布于 2013-03-18 04:48:55

一个能完成我想要的工作的示例:

代码语言:javascript
复制
    final int SERVER_PORT = 9000;
    final String SERVER_IP = "10.0.0.201";

    AsynchronousChannelGroup group = null;
    try {
        group = AsynchronousChannelGroup.withThreadPool(threadPool);
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    // Create asynchronous server-socket channel bound to the default group.
    AsynchronousServerSocketChannel asynchronousServerSocketChannel = AsynchronousServerSocketChannel.open(group);
    if ( asynchronousServerSocketChannel.isOpen() ) {
        // Bind to local address
        asynchronousServerSocketChannel.bind(new InetSocketAddress(SERVER_IP, SERVER_PORT),
                SERVER_SOCKET_CHANNEL_BACKLOG);
        // Display a waiting message
        System.out.println("Waiting for connections on ip:port " + SERVER_IP + ":" + SERVER_PORT);
        while (true) { // Not good?
            Future<AsynchronousSocketChannel> asynchronousSocketChannelFuture = asynchronousServerSocketChannel
                    .accept();
            final AsynchronousSocketChannel asynchronousSocketChannel = asynchronousSocketChannelFuture.get();

            final SocketAddress remoteAddress = asynchronousSocketChannel.getRemoteAddress();

            System.out.println("Incoming connection from: " + remoteAddress);
            final ByteBuffer incomingBuffer = ByteBuffer.allocateDirect(1024);

            // Time to receive data.
            asynchronousSocketChannel.read(incomingBuffer, incomingBuffer,
                    new CompletionHandler<Integer, ByteBuffer>() {

                        public void completed( Integer result, ByteBuffer buffer ) {
                         // Why flip it?
                            buffer.flip();
                            String msgReceived = Charset.defaultCharset().decode(buffer).toString();
                            System.out.print("Got stuff from the network: " + msgReceived);

                            // Empty the buffer, and listen for new
                            // messages.
                            incomingBuffer.clear();
                            asynchronousSocketChannel.read(incomingBuffer, incomingBuffer, this);
                        }

                        public void failed( Throwable exc, ByteBuffer buffer ) {
                            if ( exc instanceof AsynchronousCloseException ) {
                                // Someone closed the connection
                                // while we where listening on it.
                                System.out.println("We listened on the socket, but someone closed it.");
                            }
                        }
                    });
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15465347

复制
相关文章

相似问题

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