简体   繁体   中英

IP address of clients in socket using NIO

Using NIO, we have bound two ports to ServerSocket class.

        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);

Now, we are also able to fetch the IP address of the clients that are connected when the the new client makes the first request, which we are adding to a vector 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());
        }
    }

However, after the connection has been made, once we start getting data from multiple clients on both the ports, is it possible to determine, the .I hope the code that I have provided is sufficient and clear to explain the situation we are having.

ServerSocketChannel is TCP, so the IP addresses at the two ends can't change.

In your line

SocketChannel channel = server.accept(); 

channel is specific to a particular client. These are the objects you will be using to communicate with each client and each one represents a single TCP session with a single remote ip/port tuple.

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

Once you get the socketChannel to be able to send back to client, you get use the functions below.

//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();

I do not see "reading" part of code, but I am sure you have one. You can try to get remote socket address (ip + port) like this:

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();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM