Java 使用NIO的套接字中客户端的IP地址
使用NIO,我们将两个端口绑定到ServerSocket类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
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()!