1

NIO を使用して、2 つのポートを ServerSocket クラスにバインドしました。

        serverChannelPrimary = ServerSocketChannel.open();
        serverChannelSecondary = ServerSocketChannel.open();

        // Retrieves a server socket associated with this channel
        serverSocketPrimary = serverChannelPrimary.socket();
        serverSocketSecondary = serverChannelSecondary.socket();

        // Opens a connection selector
        connectionSelector = Selector.open();

        // Bind the specified port num
        serverSocketPrimary.bind(new InetSocketAddress(portOne));
        serverSocketSecondary.bind(new InetSocketAddress(portTwo));

        // Set nonblocking mode for the listening socket
        serverChannelPrimary.configureBlocking(false);
        serverChannelSecondary.configureBlocking(false);

        // Register the ServerSocketChannel with the Selector
        serverChannelPrimary.register(connectionSelector, SelectionKey.OP_ACCEPT);
        serverChannelSecondary.register(connectionSelector, SelectionKey.OP_ACCEPT);

これで、新しいクライアントが最初のリクエストを行ったときに接続されているクライアントの IP アドレスをフェッチすることもできます。これをベクトル clientIps に追加します。

    while (isActive) {
        try {
            numberOfKeys = 0;
            numberOfKeys = connectionSelector.select(timeOut);
            if (numberOfKeys == 0) {
                continue; // None of request available
            }
            // Get iterator through the selected keys list
            Iterator<SelectionKey> iterKeys = connectionSelector
                    .selectedKeys().iterator();
            while (iterKeys.hasNext()) {
                try {
                    SelectionKey selectedKey = (SelectionKey) iterKeys
                            .next();
                    // Verify the key validity
                    if (!selectedKey.isValid()) {
                        logger.error("Received key is invalid");
                        continue;
                    } else if (selectedKey.isAcceptable()) {
                        // Accept the client request
                        ServerSocketChannel server = (ServerSocketChannel) selectedKey
                                .channel();
                        SocketChannel channel = server.accept();
                        // Get the socket associated with this channel
                        Socket clientInfo = channel.socket();
                        logger.debug("Application got client request from (Host name:"
                                + clientInfo.getInetAddress().getHostName()
                                + ",Ip address:"
                                + clientInfo.getInetAddress()
                                        .getHostAddress()
                                + ",port:"
                                + clientInfo.getPort());

                        String clientAddress=clientInfo.getInetAddress().getHostAddress();
                        if(!clientIps.contains(clientAddress)){
                            clientIps.add(clientAddress);
                        }

                        logger.debug("List of client : "+clientIps);

                        clientMgr.includeClient(channel);
                    }
                } catch (Exception e) {
                    logger.error(e.getMessage());
                } finally {
                    logger.debug("Since this key has been handled, remove the SelectedKey from the selector list.");
                    iterKeys.remove();
                }

            }

        } catch (Exception e) {
            logger.error(e.getMessage());
        }
    }

ただし、接続が確立された後、両方のポートで複数のクライアントからデータを取得し始めると、各クライアントがデータを送信するたびに各クライアントの IP アドレスを特定できます。私が提供したコードが、私たちの状況を説明するのに十分かつ明確であることを願っています.

4

4 に答える 4

1

ServerSocketChannelはTCPであるため、両端のIPアドレスを変更することはできません。

あなたのラインで

SocketChannel channel = server.accept(); 

チャネルは特定のクライアントに固有です。これらは、各クライアントとの通信に使用するオブジェクトであり、各オブジェクトは、単一のリモートIP/ポートタプルを持つ単一のTCPセッションを表します。

于 2012-05-19T11:32:28.137 に答える
1

を呼び出しSocketChannel.socket().getSocketAddress()て、特定の SocketChannel のリモート アドレスを取得できます。

于 2012-05-19T11:49:20.753 に答える
0

socketChannel をクライアントに送り返すことができるようになると、以下の関数を使用できるようになります。

//Not complete example
SocketChannel ssc;
/* after accepting and other such required operations */

ssc.socket().getInetAddress().toString();
/**
Returns:
the remote IP address to which this socket is connected, or null if the socket is not connected. 

will return 10.50.10.20 as a string
*/

//To get remote port as an int
ssc.socket().getPort();
于 2015-08-26T12:14:53.653 に答える