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

Java 使用NIO的套接字中客户端的IP地址,java,sockets,nio,Java,Sockets,Nio,使用NIO,我们将两个端口绑定到ServerSocket类 serverChannelPrimary = ServerSocketChannel.open(); serverChannelSecondary = ServerSocketChannel.open(); // Retrieves a server socket associated with this channel serverSocketPrimary = ser

使用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());
        }
    }
while(isActive){
试一试{
numberOfKeys=0;
numberOfKeys=连接选择器。选择(超时);
如果(numberOfKeys==0){
continue;//所有请求都不可用
}
//通过“选定关键点”列表获取迭代器
迭代器iterKeys=连接选择器
.selectedKeys().iterator();
while(iterKeys.hasNext()){
试一试{
SelectionKey selectedKey=(SelectionKey)iterKeys
.next();
//验证密钥的有效性
如果(!selectedKey.isValid()){
logger.错误(“收到的密钥无效”);
继续;
}else if(selectedKey.isAcceptable()){
//接受客户的请求
ServerSocketChannel server=(ServerSocketChannel)selectedKey
.channel();
SocketChannel通道=server.accept();
//获取与此通道关联的套接字
Socket clientInfo=channel.Socket();
debug(“应用程序从(主机名:
+clientInfo.getInetAddress().getHostName()
+,Ip地址:
+clientInfo.getInetAddress()
.getHostAddress()
+,端口:
+getPort());
字符串clientAddress=clientInfo.getInetAddress().getHostAddress();
如果(!clientIps.contains(clientAddress)){
clientIps.add(clientAddress);
}
调试(“客户端列表:+clientIps”);
客户经理,包括客户(渠道);
}
}捕获(例外e){
logger.error(例如getMessage());
}最后{
debug(“由于已处理此键,请从选择器列表中删除SelectedKey。”);
iterKeys.remove();
}
}
}捕获(例外e){
logger.error(例如getMessage());
}
}

但是,在建立连接后,一旦我们开始从两个端口上的多个客户端获取数据,是否可以在每个客户端发送数据时确定每个客户端的IP地址。我希望我提供的代码足以清楚地解释我们的情况。

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

你行吗

SocketChannel channel = server.accept(); 

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

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

一旦获得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();
我看不到代码的“读取”部分,但我确信您有一个。您可以尝试获取远程套接字地址(ip+端口),如下所示:

if(selectionKey.isReadable()){
SocketChannel客户端=(SocketChannel)selectionKey.channel();
//您可以在这里从给定的套接字读取数据;client.read(buffer);
//还可以获取远程(以及本地)地址
client.getRemoteAddress();
}

您已将ServerSocketChannel的两个实例绑定到两个不同的端口。Java 7允许将其简化为SocketChannel.getSocketAddress()!