使用Java获取当前机器的IP地址 [英] Getting the IP address of the current machine using Java

查看:55
本文介绍了使用Java获取当前机器的IP地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试开发一个系统,其中有不同的节点运行在不同的系统或同一系统的不同端口上.

I am trying to develop a system where there are different nodes that are run on different system or on different ports on the same system.

现在所有节点都创建一个 Socket,其目标 IP 作为一个特殊节点的 IP,称为引导节点.然后节点创建自己的 ServerSocket 并开始侦听连接.

Now all the nodes create a Socket with a target IP as the IP of a special node known as a bootstrapping node. The nodes then create their own ServerSocket and start listening for connections.

引导节点维护一个节点列表并在被查询时返回它们.

The bootstrapping node maintains a list of Nodes and returns them on being queried.

现在我需要的是节点必须将其 IP 注册到引导节点.一旦客户端连接到引导节点的 ServerSocket ,我尝试使用 cli.getInetAddress() 但这没有用.

Now what I need is the node must register its IP to the bootstrapping node. I tried using cli.getInetAddress() once the client connects to the ServerSocket of bootstrapping node but that didn't work.

  1. 如果可用,我需要客户端注册其 PPP IP;
  2. 否则为 LAN IP(如果可用);
  3. 否则它必须注册 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

My PPP Connection IP address is: 117.204.44.192 but the above returns me 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 地址,但我如何区分它们?这是我得到的输出:

I am able to get all the IP addresses associated all NetworkInterfaces, but how do I distinguish them? This is the output I am getting:

127.0.0.1
192.168.1.2
192.168.56.1
117.204.44.19

推荐答案

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 不需要可达.

This way works well when there are multiple network interfaces. It always returns the preferred outbound IP. The destination 8.8.8.8 is not needed to be reachable.

Connect 在 UDP 套接字上具有以下效果:它设置发送/接收的目的地,丢弃来自其他地址的所有数据包,并且 - 这就是我们使用的 - 将套接字传输到已连接" 状态,设置其适当的字段.这包括根据系统的路由表检查到目的地的路由是否存在,并相应地设置本地端点.最后一部分似乎没有正式记录,但它看起来像是 Berkeley 套接字 API 的一个组成部分(UDP连接"状态的副作用),它可以在 Windows 和 Linux 的跨版本和发行版中可靠地工作.

Connect on a UDP socket has the following effect: it sets the destination for Send/Recv, discards all packets from other addresses, and - which is what we use - transfers the socket into "connected" state, settings its appropriate fields. This includes checking the existence of the route to the destination according to the system's routing table and setting the local endpoint accordingly. The last part seems to be undocumented officially but it looks like an integral trait of Berkeley sockets API (a side effect of UDP "connected" state) that works reliably in both Windows and Linux across versions and distributions.

因此,此方法将提供用于连接到指定远程主机的本地地址.没有建立真正的连接,因此指定的远程 ip 可能无法访问.

So, this method will give the local address that would be used to connect to the specified remote host. There is no real connection established, hence the specified remote ip can be unreachable.

正如 @macomgil 所说,对于 MacOS,您可以这样做:

As @macomgil says, for MacOS you can do this:

Socket socket = new Socket();
socket.connect(new InetSocketAddress("google.com", 80));
System.out.println(socket.getLocalAddress());

这篇关于使用Java获取当前机器的IP地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆