1

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

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

    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/server 端重置(如果移除睡眠则立即重置)。

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

4

1 回答 1

0

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

    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.");
                            }
                        }
                    });
        }
    }
}
于 2013-03-17T20:48:55.443 回答