我正在尝试开发一个系统,其中有不同的节点在不同的系统或同一系统的不同端口上运行。
现在所有节点都创建一个带有目标 IP 的 Socket,作为称为引导节点的特殊节点的 IP。然后节点创建自己的 ServerSocket
并开始侦听连接。
引导节点维护一个节点列表并在被查询时返回它们。
现在我需要的是节点必须将其 IP 注册到引导节点。一旦客户端连接到引导节点的 ServerSocket
,我就尝试使用 cli.getInetAddress()
,但这不起作用。
如果可用,我需要客户端注册其 PPP IP;否则 LAN IP(如果可用);否则它必须注册 127.0.0.1 假设它是同一台计算机。
使用代码:
System.out.println(Inet4Address.getLocalHost().getHostAddress());
或者
System.out.println(InetAddress.getLocalHost().getHostAddress());
我的 PPP 连接 IP 地址是:117.204.44.192 但上面返回我 192.168.1.2
编辑
我正在使用以下代码:
Enumeration e = NetworkInterface.getNetworkInterfaces();
while(e.hasMoreElements())
{
NetworkInterface n = (NetworkInterface) e.nextElement();
Enumeration ee = n.getInetAddresses();
while (ee.hasMoreElements())
{
InetAddress i = (InetAddress) ee.nextElement();
System.out.println(i.getHostAddress());
}
}
我能够获取与所有 NetworkInterface
关联的所有 IP 地址,但如何区分它们?这是我得到的输出:
127.0.0.1
192.168.1.2
192.168.56.1
117.204.44.19
在最一般的情况下,这可能有点棘手。
从表面上看,InetAddress.getLocalHost()
应该为您提供此主机的 IP 地址。问题是一台主机可能有很多网络接口,而一个接口可能绑定到多个 IP 地址。最重要的是,并非所有 IP 地址都可以在您的机器或 LAN 之外访问。例如,它们可以是虚拟网络设备的 IP 地址、专用网络 IP 地址等。
这意味着 InetAddress.getLocalHost()
返回的 IP 地址可能不适合使用。
你怎么能处理这个?
一种方法是使用 NetworkInterface.getNetworkInterfaces() 来获取主机上所有已知的网络接口,然后遍历每个 NI 的地址。
另一种方法是(以某种方式)获取主机的外部广告 FQDN,并使用 InetAddress.getByName() 查找主 IP 地址。 (但是您如何获得它,以及如何处理基于 DNS 的负载均衡器?)
前面的一个变体是从配置文件或命令行参数中获取首选的 FQDN。
另一种变体是从配置文件或命令行参数中获取首选 IP 地址。
总之,InetAddress.getLocalHost()
通常会起作用,但您可能需要为代码在“复杂”网络环境中运行的情况提供替代方法。
我能够获得与所有网络接口相关的所有 IP 地址,但我如何区分它们?
127.xxx.xxx.xxx 范围内的任何地址都是“环回”地址。它仅对“此”主机可见。
192.168.xxx.xxx 范围内的任何地址都是私有(又名站点本地)IP 地址。这些是为组织内部使用而保留的。这同样适用于 10.xxx.xxx.xxx 地址和 172.16.xxx.xxx 到 172.31.xxx.xxx。
169.254.xxx.xxx 范围内的地址是链接本地 IP 地址。这些保留用于单个网段。
224.xxx.xxx.xxx 到 239.xxx.xxx.xxx 范围内的地址是多播地址。
地址 255.255.255.255 是广播地址。
其他任何内容都应该是有效的公共点对点 IPv4 地址。
事实上,InetAddress API 提供了用于测试环回、链路本地、站点本地、多播和广播地址的方法。您可以使用这些来确定您返回的哪些 IP 地址是最合适的。
import java.net.DatagramSocket;
import java.net.InetAddress;
try(final DatagramSocket socket = new DatagramSocket()){
socket.connect(InetAddress.getByName("8.8.8.8"), 10002);
ip = socket.getLocalAddress().getHostAddress();
}
当有多个网络接口时,这种方式效果很好。它总是返回首选的出站 IP。目的地 8.8.8.8
不需要可到达。
Connect
在 UDP 套接字上具有以下效果:它设置发送/接收的目标,丢弃来自其他地址的所有数据包,并且 - 这就是我们使用的 - 将套接字转换为“连接”状态,设置其适当的字段。这包括根据系统的路由表检查到目的地的路由是否存在,并相应地设置本地端点。最后一部分似乎没有正式记录,但它看起来像是 Berkeley 套接字 API 的一个整体特征(UDP“连接”状态的副作用),它可以在 Windows 和 Linux 中跨版本和发行版可靠地工作。
因此,此方法将提供用于连接到指定远程主机的本地地址。没有建立真正的连接,因此指定的远程 ip 可能无法访问。
编辑:
正如 @macomgil 所说,对于 MacOS,您可以这样做:
Socket socket = new Socket();
socket.connect(new InetSocketAddress("google.com", 80));
System.out.println(socket.getLocalAddress());
在此处发布测试来自 https://issues.apache.org/jira/browse/JCS-40 的 IP 模糊解决方法代码(InetAddress.getLocalHost() 在 Linux 系统上模糊):
/**
* Returns an <code>InetAddress</code> object encapsulating what is most likely the machine's LAN IP address.
* <p/>
* This method is intended for use as a replacement of JDK method <code>InetAddress.getLocalHost</code>, because
* that method is ambiguous on Linux systems. Linux systems enumerate the loopback network interface the same
* way as regular LAN network interfaces, but the JDK <code>InetAddress.getLocalHost</code> method does not
* specify the algorithm used to select the address returned under such circumstances, and will often return the
* loopback address, which is not valid for network communication. Details
* <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4665037">here</a>.
* <p/>
* This method will scan all IP addresses on all network interfaces on the host machine to determine the IP address
* most likely to be the machine's LAN address. If the machine has multiple IP addresses, this method will prefer
* a site-local IP address (e.g. 192.168.x.x or 10.10.x.x, usually IPv4) if the machine has one (and will return the
* first site-local address if the machine has more than one), but if the machine does not hold a site-local
* address, this method will return simply the first non-loopback address found (IPv4 or IPv6).
* <p/>
* If this method cannot find a non-loopback address using this selection algorithm, it will fall back to
* calling and returning the result of JDK method <code>InetAddress.getLocalHost</code>.
* <p/>
*
* @throws UnknownHostException If the LAN address of the machine cannot be found.
*/
private static InetAddress getLocalHostLANAddress() throws UnknownHostException {
try {
InetAddress candidateAddress = null;
// Iterate all NICs (network interface cards)...
for (Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements();) {
NetworkInterface iface = (NetworkInterface) ifaces.nextElement();
// Iterate all IP addresses assigned to each card...
for (Enumeration inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();) {
InetAddress inetAddr = (InetAddress) inetAddrs.nextElement();
if (!inetAddr.isLoopbackAddress()) {
if (inetAddr.isSiteLocalAddress()) {
// Found non-loopback site-local address. Return it immediately...
return inetAddr;
}
else if (candidateAddress == null) {
// Found non-loopback address, but not necessarily site-local.
// Store it as a candidate to be returned if site-local address is not subsequently found...
candidateAddress = inetAddr;
// Note that we don't repeatedly assign non-loopback non-site-local addresses as candidates,
// only the first. For subsequent iterations, candidate will be non-null.
}
}
}
}
if (candidateAddress != null) {
// We did not find a site-local address, but we found some other non-loopback address.
// Server might have a non-site-local address assigned to its NIC (or it might be running
// IPv6 which deprecates the "site-local" concept).
// Return this non-loopback candidate address...
return candidateAddress;
}
// At this point, we did not find a non-loopback address.
// Fall back to returning whatever InetAddress.getLocalHost() returns...
InetAddress jdkSuppliedAddress = InetAddress.getLocalHost();
if (jdkSuppliedAddress == null) {
throw new UnknownHostException("The JDK InetAddress.getLocalHost() method unexpectedly returned null.");
}
return jdkSuppliedAddress;
}
catch (Exception e) {
UnknownHostException unknownHostException = new UnknownHostException("Failed to determine LAN address: " + e);
unknownHostException.initCause(e);
throw unknownHostException;
}
}
为此,您可以使用 java 的 InetAddress 类。
InetAddress IP=InetAddress.getLocalHost();
System.out.println("IP of my system is := "+IP.getHostAddress());
我的系统的输出 = IP of my system is := 10.100.98.228
以文本形式返回 IP 地址字符串。
或者你也可以这样做
InetAddress IP=InetAddress.getLocalHost();
System.out.println(IP.toString());
输出 = IP of my system is := RanRag-PC/10.100.98.228
clientSocket.getInetAddress().getHostName();
当你在寻找你的“本地”地址时,你应该注意每台机器不仅有一个网络接口,而且每个接口都可以有自己的本地地址。这意味着您的机器始终拥有多个“本地”地址。
当您连接到不同的端点时,将自动选择使用不同的“本地”地址。例如,当您连接到 google.com
时,您使用的是“外部”本地地址;但是当您连接到 localhost
时,您的本地地址始终是 localhost
本身,因为 localhost 只是一个环回。
下面展示了如何在与 google.com
通信时找到您的本地地址:
Socket socket = new Socket();
socket.connect(new InetSocketAddress("google.com", 80));
System.out.println(socket.getLocalAddress());
socket.close();
scala 中的示例(在 sbt 文件中有用):
import collection.JavaConverters._
import java.net._
def getIpAddress: String = {
val enumeration = NetworkInterface.getNetworkInterfaces.asScala.toSeq
val ipAddresses = enumeration.flatMap(p =>
p.getInetAddresses.asScala.toSeq
)
val address = ipAddresses.find { address =>
val host = address.getHostAddress
host.contains(".") && !address.isLoopbackAddress
}.getOrElse(InetAddress.getLocalHost)
address.getHostAddress
}
编辑 1:更新的代码,因为上一个链接,不再存在
import java.io.*;
import java.net.*;
public class GetMyIP {
public static void main(String[] args) {
URL url = null;
BufferedReader in = null;
String ipAddress = "";
try {
url = new URL("http://bot.whatismyipaddress.com");
in = new BufferedReader(new InputStreamReader(url.openStream()));
ipAddress = in.readLine().trim();
/* IF not connected to internet, then
* the above code will return one empty
* String, we can check it's length and
* if length is not greater than zero,
* then we can go for LAN IP or Local IP
* or PRIVATE IP
*/
if (!(ipAddress.length() > 0)) {
try {
InetAddress ip = InetAddress.getLocalHost();
System.out.println((ip.getHostAddress()).trim());
ipAddress = (ip.getHostAddress()).trim();
} catch(Exception exp) {
ipAddress = "ERROR";
}
}
} catch (Exception ex) {
// This try will give the Private IP of the Host.
try {
InetAddress ip = InetAddress.getLocalHost();
System.out.println((ip.getHostAddress()).trim());
ipAddress = (ip.getHostAddress()).trim();
} catch(Exception exp) {
ipAddress = "ERROR";
}
//ex.printStackTrace();
}
System.out.println("IP Address: " + ipAddress);
}
}
实际版本:这停止工作
希望这个片段可以帮助您实现这一目标:
// Method to get the IP Address of the Host.
private String getIP()
{
// This try will give the Public IP Address of the Host.
try
{
URL url = new URL("http://automation.whatismyip.com/n09230945.asp");
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String ipAddress = new String();
ipAddress = (in.readLine()).trim();
/* IF not connected to internet, then
* the above code will return one empty
* String, we can check it's length and
* if length is not greater than zero,
* then we can go for LAN IP or Local IP
* or PRIVATE IP
*/
if (!(ipAddress.length() > 0))
{
try
{
InetAddress ip = InetAddress.getLocalHost();
System.out.println((ip.getHostAddress()).trim());
return ((ip.getHostAddress()).trim());
}
catch(Exception ex)
{
return "ERROR";
}
}
System.out.println("IP Address is : " + ipAddress);
return (ipAddress);
}
catch(Exception e)
{
// This try will give the Private IP of the Host.
try
{
InetAddress ip = InetAddress.getLocalHost();
System.out.println((ip.getHostAddress()).trim());
return ((ip.getHostAddress()).trim());
}
catch(Exception ex)
{
return "ERROR";
}
}
}
whatismyip.com
关闭了一段时间,您的应用程序也会关闭:(。或者它会返回垃圾数据并导致意外行为。此外,这返回 whatismyip.com
可检测到的最外层 IP 地址,不一定是您正在使用的机器的 IP 地址。
private static InetAddress getLocalAddress(){
try {
Enumeration<NetworkInterface> b = NetworkInterface.getNetworkInterfaces();
while( b.hasMoreElements()){
for ( InterfaceAddress f : b.nextElement().getInterfaceAddresses())
if ( f.getAddress().isSiteLocalAddress())
return f.getAddress();
}
} catch (SocketException e) {
e.printStackTrace();
}
return null;
}
首先导入类
import java.net.InetAddress;
在班上
InetAddress iAddress = InetAddress.getLocalHost();
String currentIp = iAddress.getHostAddress();
System.out.println("Current IP address : " +currentIp); //gives only host address
您可以使用 java.net.InetAddress
API。尝试这个 :
InetAddress.getLocalHost().getHostAddress();
这是上面接受的答案的一个工作示例!此 NetIdentity 类将存储内部主机 ip 以及本地环回。如果您在基于 DNS 的服务器上,如上所述,您可能需要添加更多检查,或者可能转到配置文件路由。
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;
/**
* Class that allows a device to identify itself on the INTRANET.
*
* @author Decoded4620 2016
*/
public class NetIdentity {
private String loopbackHost = "";
private String host = "";
private String loopbackIp = "";
private String ip = "";
public NetIdentity(){
try{
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while(interfaces.hasMoreElements()){
NetworkInterface i = interfaces.nextElement();
if(i != null){
Enumeration<InetAddress> addresses = i.getInetAddresses();
System.out.println(i.getDisplayName());
while(addresses.hasMoreElements()){
InetAddress address = addresses.nextElement();
String hostAddr = address.getHostAddress();
// local loopback
if(hostAddr.indexOf("127.") == 0 ){
this.loopbackIp = address.getHostAddress();
this.loopbackHost = address.getHostName();
}
// internal ip addresses (behind this router)
if( hostAddr.indexOf("192.168") == 0 ||
hostAddr.indexOf("10.") == 0 ||
hostAddr.indexOf("172.16") == 0 ){
this.host = address.getHostName();
this.ip = address.getHostAddress();
}
System.out.println("\t\t-" + address.getHostName() + ":" + address.getHostAddress() + " - "+ address.getAddress());
}
}
}
}
catch(SocketException e){
}
try{
InetAddress loopbackIpAddress = InetAddress.getLocalHost();
this.loopbackIp = loopbackIpAddress.getHostName();
System.out.println("LOCALHOST: " + loopbackIp);
}
catch(UnknownHostException e){
System.err.println("ERR: " + e.toString());
}
}
public String getLoopbackHost(){
return loopbackHost;
}
public String getHost(){
return host;
}
public String getIp(){
return ip;
}
public String getLoopbackIp(){
return loopbackIp;
}
}
当我运行这段代码时,我实际上得到了这样的打印输出:
Software Loopback Interface 1
-127.0.0.1:127.0.0.1 - [B@19e1023e
-0:0:0:0:0:0:0:1:0:0:0:0:0:0:0:1 - [B@7cef4e59
Broadcom 802.11ac Network Adapter
-VIKING.yourisp.com:192.168.1.142 - [B@64b8f8f4
-fe80:0:0:0:81fa:31d:21c9:85cd%wlan0:fe80:0:0:0:81fa:31d:21c9:85cd%wlan0 - [B@2db0f6b2
Microsoft Kernel Debug Network Adapter
Intel Edison USB RNDIS Device
Driver for user-mode network applications
Cisco Systems VPN Adapter for 64-bit Windows
VirtualBox Host-Only Ethernet Adapter
-VIKING:192.168.56.1 - [B@3cd1f1c8
-VIKING:fe80:0:0:0:d599:3cf0:5462:cb7%eth4 - [B@3a4afd8d
LogMeIn Hamachi Virtual Ethernet Adapter
-VIKING:25.113.118.39 - [B@1996cd68
-VIKING:2620:9b:0:0:0:0:1971:7627 - [B@3339ad8e
-VIKING:fe80:0:0:0:51bf:994d:4656:8486%eth5 - [B@555590
Bluetooth Device (Personal Area Network)
-fe80:0:0:0:4c56:8009:2bca:e16b%eth6:fe80:0:0:0:4c56:8009:2bca:e16b%eth6 - [B@3c679bde
Bluetooth Device (RFCOMM Protocol TDI)
Intel(R) Ethernet Connection (2) I218-V
-fe80:0:0:0:4093:d169:536c:7c7c%eth7:fe80:0:0:0:4093:d169:536c:7c7c%eth7 - [B@16b4a017
Microsoft Wi-Fi Direct Virtual Adapter
-fe80:0:0:0:103e:cdf0:c0ac:1751%wlan1:fe80:0:0:0:103e:cdf0:c0ac:1751%wlan1 - [B@8807e25
VirtualBox Host-Only Ethernet Adapter-HHD Software NDIS 6.0 Filter Driver-0000
VirtualBox Host-Only Ethernet Adapter-WFP Native MAC Layer LightWeight Filter-0000
VirtualBox Host-Only Ethernet Adapter-HHD Software NDIS 6.0 Filter Driver-0001
VirtualBox Host-Only Ethernet Adapter-HHD Software NDIS 6.0 Filter Driver-0002
VirtualBox Host-Only Ethernet Adapter-VirtualBox NDIS Light-Weight Filter-0000
VirtualBox Host-Only Ethernet Adapter-HHD Software NDIS 6.0 Filter Driver-0003
VirtualBox Host-Only Ethernet Adapter-QoS Packet Scheduler-0000
VirtualBox Host-Only Ethernet Adapter-HHD Software NDIS 6.0 Filter Driver-0004
VirtualBox Host-Only Ethernet Adapter-WFP 802.3 MAC Layer LightWeight Filter-0000
VirtualBox Host-Only Ethernet Adapter-HHD Software NDIS 6.0 Filter Driver-0005
Intel(R) Ethernet Connection (2) I218-V-HHD Software NDIS 6.0 Filter Driver-0000
Intel(R) Ethernet Connection (2) I218-V-WFP Native MAC Layer LightWeight Filter-0000
Intel(R) Ethernet Connection (2) I218-V-HHD Software NDIS 6.0 Filter Driver-0001
Intel(R) Ethernet Connection (2) I218-V-Shrew Soft Lightweight Filter-0000
Intel(R) Ethernet Connection (2) I218-V-HHD Software NDIS 6.0 Filter Driver-0002
Intel(R) Ethernet Connection (2) I218-V-VirtualBox NDIS Light-Weight Filter-0000
Intel(R) Ethernet Connection (2) I218-V-HHD Software NDIS 6.0 Filter Driver-0003
Intel(R) Ethernet Connection (2) I218-V-QoS Packet Scheduler-0000
Intel(R) Ethernet Connection (2) I218-V-HHD Software NDIS 6.0 Filter Driver-0004
Intel(R) Ethernet Connection (2) I218-V-WFP 802.3 MAC Layer LightWeight Filter-0000
Intel(R) Ethernet Connection (2) I218-V-HHD Software NDIS 6.0 Filter Driver-0005
Broadcom 802.11ac Network Adapter-WFP Native MAC Layer LightWeight Filter-0000
Broadcom 802.11ac Network Adapter-Virtual WiFi Filter Driver-0000
Broadcom 802.11ac Network Adapter-Native WiFi Filter Driver-0000
Broadcom 802.11ac Network Adapter-HHD Software NDIS 6.0 Filter Driver-0003
Broadcom 802.11ac Network Adapter-Shrew Soft Lightweight Filter-0000
Broadcom 802.11ac Network Adapter-HHD Software NDIS 6.0 Filter Driver-0004
Broadcom 802.11ac Network Adapter-VirtualBox NDIS Light-Weight Filter-0000
Broadcom 802.11ac Network Adapter-HHD Software NDIS 6.0 Filter Driver-0005
Broadcom 802.11ac Network Adapter-QoS Packet Scheduler-0000
Broadcom 802.11ac Network Adapter-HHD Software NDIS 6.0 Filter Driver-0006
Broadcom 802.11ac Network Adapter-WFP 802.3 MAC Layer LightWeight Filter-0000
Broadcom 802.11ac Network Adapter-HHD Software NDIS 6.0 Filter Driver-0007
Microsoft Wi-Fi Direct Virtual Adapter-WFP Native MAC Layer LightWeight Filter-0000
Microsoft Wi-Fi Direct Virtual Adapter-Native WiFi Filter Driver-0000
Microsoft Wi-Fi Direct Virtual Adapter-HHD Software NDIS 6.0 Filter Driver-0002
Microsoft Wi-Fi Direct Virtual Adapter-Shrew Soft Lightweight Filter-0000
Microsoft Wi-Fi Direct Virtual Adapter-HHD Software NDIS 6.0 Filter Driver-0003
Microsoft Wi-Fi Direct Virtual Adapter-VirtualBox NDIS Light-Weight Filter-0000
Microsoft Wi-Fi Direct Virtual Adapter-HHD Software NDIS 6.0 Filter Driver-0004
Microsoft Wi-Fi Direct Virtual Adapter-QoS Packet Scheduler-0000
Microsoft Wi-Fi Direct Virtual Adapter-HHD Software NDIS 6.0 Filter Driver-0005
Microsoft Wi-Fi Direct Virtual Adapter-WFP 802.3 MAC Layer LightWeight Filter-0000
Microsoft Wi-Fi Direct Virtual Adapter-HHD Software NDIS 6.0 Filter Driver-0006
为了我的使用,我正在设置一个 Upnp 服务器,它有助于理解我正在寻找的“模式”。返回的一些对象是以太网适配器、网络适配器、虚拟网络适配器、驱动程序和 VPN 客户端适配器。也不是所有东西都有地址。所以你会想要跳过那些没有的接口对象。
您还可以将此添加到当前 NetworkInterface i
的循环中
while(interfaces.hasMoreElements()){
Enumeration<InetAddress> addresses = i.getInetAddresses();
System.out.println(i.getDisplayName());
System.out.println("\t- name:" + i.getName());
System.out.println("\t- idx:" + i.getIndex());
System.out.println("\t- max trans unit (MTU):" + i.getMTU());
System.out.println("\t- is loopback:" + i.isLoopback());
System.out.println("\t- is PPP:" + i.isPointToPoint());
System.out.println("\t- isUp:" + i.isUp());
System.out.println("\t- isVirtual:" + i.isVirtual());
System.out.println("\t- supportsMulticast:" + i.supportsMulticast());
}
您将在输出中看到如下信息:
Software Loopback Interface 1
- name:lo
- idx:1
- max trans unit (MTU):-1
- is loopback:true
- is PPP:false
- isUp:true
- isVirtual:false
- supportsMulticast:true
-ADRESS: [127.0.0.1(VIKING-192.168.56.1)]127.0.0.1:127.0.0.1 - [B@19e1023e
-ADRESS: [0:0:0:0:0:0:0:1(VIKING-192.168.56.1)]0:0:0:0:0:0:0:1:0:0:0:0:0:0:0:1 - [B@7cef4e59
Broadcom 802.11ac Network Adapter
- name:wlan0
- idx:2
- max trans unit (MTU):1500
- is loopback:false
- is PPP:false
- isUp:true
- isVirtual:false
- supportsMulticast:true
-ADRESS: [VIKING.monkeybrains.net(VIKING-192.168.56.1)]VIKING.monkeybrains.net:192.168.1.142 - [B@64b8f8f4
-ADRESS: [fe80:0:0:0:81fa:31d:21c9:85cd%wlan0(VIKING-192.168.56.1)]fe80:0:0:0:81fa:31d:21c9:85cd%wlan0:fe80:0:0:0:81fa:31d:21c9:85cd%wlan0 - [B@2db0f6b2
Microsoft Kernel Debug Network Adapter
- name:eth0
- idx:3
- max trans unit (MTU):-1
- is loopback:false
- is PPP:false
- isUp:false
- isVirtual:false
- supportsMulticast:true
使用 InetAddress.getLocalHost() 获取本地地址
import java.net.InetAddress;
try {
InetAddress addr = InetAddress.getLocalHost();
System.out.println(addr.getHostAddress());
} catch (UnknownHostException e) {
}
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
public class IpAddress {
NetworkInterface ifcfg;
Enumeration<InetAddress> addresses;
String address;
public String getIpAddress(String host) {
try {
ifcfg = NetworkInterface.getByName(host);
addresses = ifcfg.getInetAddresses();
while (addresses.hasMoreElements()) {
address = addresses.nextElement().toString();
address = address.replace("/", "");
}
} catch (Exception e) {
e.printStackTrace();
}
return ifcfg.toString();
}
}
一种相当简单的方法,似乎正在工作......
String getPublicIPv4() throws UnknownHostException, SocketException{
Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
String ipToReturn = null;
while(e.hasMoreElements())
{
NetworkInterface n = (NetworkInterface) e.nextElement();
Enumeration<InetAddress> ee = n.getInetAddresses();
while (ee.hasMoreElements())
{
InetAddress i = (InetAddress) ee.nextElement();
String currentAddress = i.getHostAddress();
logger.trace("IP address "+currentAddress+ " found");
if(!i.isSiteLocalAddress()&&!i.isLoopbackAddress() && validate(currentAddress)){
ipToReturn = currentAddress;
}else{
System.out.println("Address not validated as public IPv4");
}
}
}
return ipToReturn;
}
private static final Pattern IPv4RegexPattern = Pattern.compile(
"^(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])$");
public static boolean validate(final String ip) {
return IPv4RegexPattern.matcher(ip).matches();
}
通常,当我尝试查找我的公共 IP 地址(如 cmyip.com 或 www.iplocation.net)时,我使用这种方式:
public static String myPublicIp() {
/*nslookup myip.opendns.com resolver1.opendns.com*/
String ipAdressDns = "";
try {
String command = "nslookup myip.opendns.com resolver1.opendns.com";
Process proc = Runtime.getRuntime().exec(command);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String s;
while ((s = stdInput.readLine()) != null) {
ipAdressDns += s + "\n";
}
} catch (IOException e) {
e.printStackTrace();
}
return ipAdressDns ;
}
如果您的机器是网络的一部分,这将获取您的网络的 IP 地址
try {
System.out.println(InetAddress.getLocalHost().getHostAddress());
} catch (UnknownHostException e) {
e.printStackTrace();
}
由于我的系统(与许多其他系统一样)具有各种网络接口。InetAddress.getLocalHost()
或 Inet4Address.getLocalHost()
只是返回了一个我不想要的。因此我不得不使用这种幼稚的方法。
InetAddress[] allAddresses = Inet4Address.getAllByName("YourComputerHostName");
InetAddress desiredAddress;
//In order to find the desired Ip to be routed by other modules (WiFi adapter)
for (InetAddress address :
allAddresses) {
if (address.getHostAddress().startsWith("192.168.2")) {
desiredAddress = address;
}
}
// Use the desired address for whatever purpose.
请注意,在这种方法中,我已经知道我想要的 IP 地址在 192.168.2
子网中。
您的计算机可以有多个 NetworkInterface
,每个都有多个 InetAddress
。如果您过滤掉任何本地地址,则提醒的地址是非本地地址,您可以有一个,没有或多个。
不幸的是,Java 中的网络 API 仍然使用(旧的)枚举而不是迭代器和流,我们可以通过将它们包装为流来应对。所以我们需要做的就是
流过所有网络接口及其地址,以及
过滤掉本地的
代码:
private Stream<InetAddress> getNonLocalIpAddresses() throws IOException {
return enumerationAsStream(NetworkInterface.getNetworkInterfaces())
.flatMap(networkInterface -> enumerationAsStream(networkInterface.getInetAddresses()))
.filter(inetAddress -> !inetAddress.isAnyLocalAddress())
.filter(inetAddress -> !inetAddress.isSiteLocalAddress())
.filter(inetAddress -> !inetAddress.isLoopbackAddress())
.filter(inetAddress -> !inetAddress.isLinkLocalAddress());
}
在我的机器上,这当前返回两个 IPv6 地址。
要获得这些 InetAdresses 中的第一个:
private String getMyIp() throws IOException {
return getNonLocalIpAddresses()
.map(InetAddress::getHostAddress)
.findFirst()
.orElseThrow(NoSuchElementException::new);
}
将枚举包装为流的方法:
public static <T> Stream<T> enumerationAsStream(Enumeration<T> e) {
return StreamSupport.stream(
Spliterators.spliteratorUnknownSize(
new Iterator<>() {
public T next() { return e.nextElement(); }
public boolean hasNext() { return e.hasMoreElements(); }
}, Spliterator.ORDERED), false);
}
use getLocalHost().getHostAddress()
发布某些内容,您可能会在网络上的另一台计算机上看到0.0.0.0
。这是解释 here 这就是我在两台计算机上使用 Gazebo 时发生的事情