我需要将一些数据发送到本地网络上的服务器的Java / Android应用程序。问题是服务器的IP地址是动态的,所以找到它的唯一方法是通过它的MAC地址查找。 这在Java中可行吗?你能看到其他任何选择吗?
答案 0 :(得分:2)
按MAC地址查找主机只能在本地网络中使用。 Mac地址是IP地址下的一层。没有基于Mac Adresses到其他网络的路由。
如果您正在寻找仅适用于本地网络的解决方案,则可以选择收听和发送到广播或多播。如果将数据包发送到广播地址,则本地网络中的每个主机都会收到此数据包,如果它是您要查找的服务器,则可以回答该数据包。多播在概念上有所不同,只有那些想要接收寻址到特定多频地址的数据包的主机才会收到此数据包。如果您正在使用多播,则需要为您的应用程序选择一个地址,每个客户端都会将数据包发送到此地址,每个要查找的服务器都会侦听此地址。甚至存在一些网络(例如一些大学网络),其中多播数据包被路由到一组有限的其他本地网络。
您可以使用具有静态IP地址的第二台服务器来查找动态serevr。无论何时更改,您的动态服务器都会告诉静态服务器他的IP地址。您的客户端会询问静态服务器以获取动态服务器的地址。这种模式适用于整个互联网,无论您的动态服务器和客户端在哪里。
此静态服务器可能是您的DNS服务器或某些dyndns提供程序的DNS服务器。但这并不仅限于DNS。 DNS旨在了解如何到达服务/服务器,但这可以通过任何协议完成。例如,如果您更喜欢Web服务,可以通过您开发的某些http / web应用程序来完成。
答案 1 :(得分:2)
只是一点警告:此代码未经测试,
尝试深入研究arp缓存,如下所示:
public static String getIpFromArpCache(String macaddr) {
if (ip == null)
return null;
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("/proc/net/arp"));
String line;
while ((line = br.readLine()) != null) {
String[] splitted = line.split(" +");
if (splitted != null && splitted.length >= 4 && macaddr.equals(splitted[3])) {
// Basic sanity check
String ip = splitted[0];
if (validateIp(ip)) {
return ip;
} else {
return null;
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
private static final String PATTERN =
"^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
"([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
"([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
"([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";
public static boolean validateIp(final String ip){
Pattern pattern = Pattern.compile(PATTERN);
Matcher matcher = pattern.matcher(ip);
return matcher.matches();
}
来自here
的修改例程答案 2 :(得分:0)
这在Java中是否可行?
不是纯Java。
没有直接将MAC地址映射到IP地址的服务。主机操作系统的网络堆栈使用ARP协议和(在Linux / UNIX上)ARP daemon将IP地址映射到MAC地址。 AFAIK,无法使用Java的ARP协议。
您可以做的最好(在Linux上)是将“arpd -l”作为外部命令运行。这将以一个定义良好的格式转储守护程序的ARP映射,Java应用程序可以读取和解析该格式。如果您的服务器在本地网络上处于活动状态,则其MAC地址将与相应的IP地址一起显示。但如果它不在本地网络上,那么它的ARP广播将无法到达你的机器,因此守护进程表中不会有条目。
最好为服务器分配静态IP地址...和DNS地址。另一种可能性是让服务器使用Dynamic DNS服务注册自己。