1

使用 NIO,我们将两个端口绑定到 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

您可以调用SocketChannel.socket().getSocketAddress()以获取任何特定 SocketChannel 的远程地址。

于 2012-05-19T11:49:20.753 回答
1

ServerSocketChannel是TCP的,所以两端的IP地址是不能改变的。

在你的行

SocketChannel channel = server.accept(); 

频道特定于特定客户。这些是您将用于与每个客户端通信的对象,每个对象代表一个带有单个远程 ip/port 元组的单个 TCP 会话。

于 2012-05-19T11:32:28.137 回答
0

我没有看到代码的“阅读”部分,但我相信你有一个。您可以尝试像这样获取远程套接字地址(ip + 端口):

if (selectionKey.isReadable()) {
    SocketChannel client = (SocketChannel) selectionKey.channel();
    // you can here read data from given socket; client.read(buffer);
    // and also get remote (and local too) address
    client.getRemoteAddress();
}
于 2020-08-21T10:28:42.680 回答
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 回答