java - 如何让异步tcp服务器继续监听 channel 而不是关闭它

标签 java networking asynchronous tcp

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

这是我的服务器代码(精简):

    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/服务器端重置(如果移除 sleep 则立即重置)。

如何阻止它返回,并让它继续收听? 我是否采取了正确的方法来解决我的初始目标?

最佳答案

一个可以满足我要求的工作示例:

    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.");
                            }
                        }
                    });
        }
    }
}

关于java - 如何让异步tcp服务器继续监听 channel 而不是关闭它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15465347/

相关文章:

java - 覆盖 jar 中的 config.properties

linux - 释放 TCP/IP 端口?

java - 远程连接到 MySQL 服务器

linux - 如何使用 netcat 更改监听规则?

javascript - Ember.js 异步模型

c# - 在异步方法主体中获取当前任务实例

java - android 如何使用 SharedPreference 编写秒表

java - 如何从不同的类在 jtextarea 上打印文本消息

Java Android - 定义导入

asp.net-mvc - 如何在 asp.net mvc 3 中使下载操作异步?