我正在创建一个文件共享应用程序,用于查找在同一网络上运行该应用程序的计算机。所以我希望我的应用程序能够发现计算机及其IP地址。使用Java可以实现此任务吗?
感谢
答案 0 :(得分:3)
这是分布式计算的基本问题之一,有两种方法在某种程度上有效:
在网络上的某个位置,您使用众所周知的主机和端口号运行Registry Service。必须可以从要运行应用程序的每个位置访问/可寻址此服务。
启动时,网络上的每个应用程序实例都会向注册表注册。
当某个机器/程序需要找到该应用程序的实例时,它会询问注册表。
问题:
您必须在不告知注册管理机构的情况下处理“离开”的应用程序实例。
如果注册表重新启动,您必须有办法恢复状态。
应用程序必须知道注册表实例的名称(或地址)和端口。
应用程序的每个实例都会侦听一个众所周知的“广播”或“多播”地址/端口。
当程序想要查找应用程序的实例时,它会发送广播/多播请求。
每个实例都会响应请求,并提供详细信息。
该程序会累积响应以构建所有“实时”实例的列表。
问题:
这不会缩放。来自M个程序的每个请求都转到N台机器并生成N个响应。随着M和N的增长,网络流量呈二次方式增长。
广播和组播都是有损的,尤其是在繁忙的网络上。
广播通常不会跨越网络边界。组播需要特殊配置。
任何一种方法都应该在具有有限数量实例的小型网络上运行。
简单的方法是确定现有的分布式计算技术,为您完成大部分工作。例如,RMI和RMI注册表,动态DNS,CORBA,JINI。
答案 1 :(得分:1)
我找到了这个问题的答案。我环顾四周,发现了这段代码。这不是最好的方法,但它有效..
import java.io.IOException;
import java.net.InetAddress;
public class networkPing {
public static void main(String[] args) throws IOException {
InetAddress localhost = InetAddress.getLocalHost();
// this code assumes IPv4 is used
byte[] ip = localhost.getAddress();
for (int i = 1; i <= 254; i++)
{
ip[3] = (byte)i;
InetAddress address = InetAddress.getByAddress(ip);
if (address.isReachable(1000))
{
System.out.println(address + " machine is turned on and can be pinged");
}
else if (!address.getHostAddress().equals(address.getHostName()))
{
System.out.println(address + " machine is known in a DNS lookup");
}
}
}
}
答案 2 :(得分:0)
你应该看看this article on jxta。它是Sun的P2P Java框架,它被大量流行的应用程序所使用。看一些使用jxta的应用程序也可能会很好,因为它们可能已经做了类似于你想做的事情。
答案 3 :(得分:0)
这里的一个问题是'同一网络'没有明确定义。你的意思是一个子网?所有节点都可以在路由器之前到达?
例如,如果您的意思是“局域网”,这在TCP中没有意义,但SAMBA可能会有所帮助。
如果可以让其他节点做出响应,可以使用适当的范围组播来解决其中一些问题。或者,如果您知道子网掩码,则可以执行IP地址算法。但是你需要首先更准确地定义你的问题。
答案 4 :(得分:0)
使用多播DNS(我不知道如何在Java / Windows上使用它)。
或使用IP广播(使用UDP)。
答案 5 :(得分:0)
每台计算机都应将DatagramPacket
发送到多播组。还从组中接收数据包。然后使用getAddress()
从数据包中获取InetAddress
个对象。
切记:要接收组播数据包,系统应加入组播组。但任何人(无需加入)都可以将数据包发送到多播组。
答案 6 :(得分:0)
I found this utility class part of Apache commons JCS (a caching library) particularly helpful, just copied it to my project since I didn't want/need to include the whole JCS library and the code is not available elsewhere separately (e.g. in apache commons-net would be nice):