使用NIO的套接字中的客户端的IP地址

时间:2012-05-19 11:20:49

标签: java sockets nio

使用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地址 。我希望我提供的代码足以清楚地解释我们所处的情况。

3 个答案:

答案 0 :(得分:1)

ServerSocketChannel是TCP,因此两端的IP地址无法更改。

在你的行

SocketChannel channel = server.accept(); 

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

答案 1 :(得分:1)

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

答案 2 :(得分: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();
}