Java:如何获取可以到达远程IP的本地接口的IP?

Java:如何获取可以到达远程IP的本地接口的IP?,java,ip-address,lookup,Java,Ip Address,Lookup,我有一个Java应用程序,它在服务提供者中注册一个服务器组件,然后将服务名称发送给客户机。客户机使用服务名称从服务提供者获取到服务器的地址。但是,服务器有几个接口,客户端只能访问其中的一个,因此必须使用正确的IP注册服务。我们通过广播发现了客户端,所以我有客户端IP和计算机网络接口的枚举。在不知道客户端IP的网络掩码的情况下,如何将IP与接口匹配 我自然而然地想象着把所有的地址都转换成INT,用他们的网络掩码大嚼本地IP,寻找“最佳匹配”,但我想知道是否有更好的方法 (这是一个企业(tm)解决方

我有一个Java应用程序,它在服务提供者中注册一个服务器组件,然后将服务名称发送给客户机。客户机使用服务名称从服务提供者获取到服务器的地址。但是,服务器有几个接口,客户端只能访问其中的一个,因此必须使用正确的IP注册服务。我们通过广播发现了客户端,所以我有客户端IP和计算机网络接口的枚举。在不知道客户端IP的网络掩码的情况下,如何将IP与接口匹配

我自然而然地想象着把所有的地址都转换成INT,用他们的网络掩码大嚼本地IP,寻找“最佳匹配”,但我想知道是否有更好的方法


(这是一个企业(tm)解决方案,因此不可选择切断服务提供商,至少不需要先进行政治竞选;)

这取决于您如何进行这项工作

示例代码多少


InetAddress有一个“.getHostAddress()”方法,可能很有用。

这通常是通过DNS完成的。该接口应在DNS中列出,以便您可以通过名称而不是地址servicehost.example.com而不是192.0.2.42访问它。

与其说是应用程序,不如说是网络管理问题

假设服务器(承载java应用程序)是多宿主的。 它可以是三个地址: 1.99.88.77.66(公共知识产权) 2.10.10.10.10(私有、内部分配的IP)

您的潜在客户可以访问哪个IP取决于网络配置

客户端可以从公共IP访问,但由于NAT,它将访问您的私有IP。 另一个例子,可能是你的客户端IP是192.168.10.10,通过NAT,它访问你的10.10.10.10 IP

您无法通过任何类型的前缀匹配来计算正确的IP(以发布您的服务)

您提到过,这是一个企业解决方案,在这种环境中,复杂的网络配置很常见

使用DNS,您的服务器主机可能是myapp.company.com 由DNS设施为客户端解析正确的IP。 您可能需要与网络人协调,并在DNS中提供适当的支持,
解决方案应该简单且更健壮。

据我所知,服务提供商在多个不同的网络上有接口。每个客户端仅位于其中一个网络上,因此只能与其中一个接口通信。服务需要发现客户端可以访问哪些接口,以便发送正确的地址。您(服务开发人员)无法控制服务部署到的网络环境,因此无法使用DNS等网络级解决方案

在许多网络设置中,路由是对称的。也就是说,从主机A到主机B的路由与从主机B到主机A的路由相同。如果您知道服务将部署到的所有环境中都存在这种情况,那么您可以安全地假设用于连接到客户端的地址可供客户端访问。例如,可以通过将
DatagramSocket
连接到客户端,然后调用其
getLocalAddress()
方法来发现该地址


如果路由是非对称的,我就无法确定客户端是否可以仅使用
java.net
API访问特定接口。如果您控制客户端实现,您可能能够让它在其广播响应数据包中包含广播源地址(应该是对其可见的服务器接口)。除此之外,您还没有提供足够的场景信息来提供具体建议。例如,了解广播广告使用的协议以及客户端对广播广告的响应是很有用的。

目前,我只需要抓取NetworkInterface.getNetworkInterfaces,遍历它们,查看它们的所有inetAddress(是的,使用getHostAddress),然后匹配前3个八位字节。但正如我所说,我不能假设255.255.255.0位掩码(或任何其他),所以我正在寻找一个更健壮的解决方案。isReachable和getByAddress的某种组合会很好,但我在API中没有找到类似的东西。“isReachable和getByAddress的某种组合会很好,但我在API中没有找到类似的东西。”-您已经有了地址,InetAddress有一个isReachable方法(int timeout)(从1.5开始),尽管根据文档“如果可以获得特权,典型的实现将使用ICMP ECHO请求,否则它将尝试在目标主机的端口7(ECHO)上建立TCP连接。”因此需要在服务计算机上启用。这是事实。我不确定在这个环境中是否设置了dns服务器,服务提供商现在只接受一个直接的IP(并且由另一个国家的一个部门拥有)。但是如果我可以使用DNS,我仍然需要为每个地址注册一个单独的名称,不是吗?我需要知道从给定的IP可以访问哪个名称,我的情况也差不多。或者DNS服务器从本质上处理这个问题吗?底层操作系统应该处理大部分低级别的套接字内容。只需创建套接字并调用get local address方法。作为最后一种手段,通过枚举您已访问的本地地址并创建套接字,将每个本地地址绑定到一个套接字,然后查看是否可以连接到客户端。但是
Socket(clientIP,port).getLocalAddress()
应该可以工作。只要网络上的路由是对称的,就应该可以工作。如果不是本地IP,则用于向客户端发送数据报的本地IP可能与客户端有权访问的IP不同。在实例化未绑定的DataSocket后,即使连接到远程IP并发送虚拟数据包,本地地址仍保持
0.0.0