我有一台服务器(在我的笔记本电脑上运行的Java应用程序)和一个客户端(在我的Android智能手机上运行的Java应用程序)。 我正在尝试从我的客户端自动查找服务器的IP地址。
现在我只是在同一局域网(192.168.1.0> 192.168.1.1.255)中循环所有IP,如果服务器(正在侦听自定义端口)接受连接,那么我找到了IP。
问题是,如果我将连接超时设置为小于200毫秒,则客户端无法找到服务器。
所以问题是,如何实现更好(更快)的方式来查找服务器IP? 我尝试过java InetAddress.isReachable()方法,但服务器似乎总是无法访问...
并且,如果没有更好的方法,您认为本地(LAN)套接字连接的超时值是多少?
答案 0 :(得分:3)
仅供其他人使用......我刚刚找到了一种非常好的方法来找到服务器IP,而不是那么半年!
这是我的解决方案:
String partialIp = "192.168.1.";
int port = 123;
int counter;
boolean found;
String ip;
Runnable tryNextIp = new Runnable() {
@Override
public void run() {
int myIp = counter++;
String targetIpTemp = partialIp + myIp;
Socket socketTemp = new Socket();
try {
socketTemp.connect(new InetSocketAddress(targetIpTemp, port), 6000);
socketTemp.close();
ip = targetIpTemp;
found = true;
} catch (IOException e) {
try {
socketTemp.close();
} catch (IOException e1) {}
}
}
};
String findIp() {
counter = 0;
found = false;
ExecutorService executorService = Executors.newFixedThreadPool(256);
for (int i=0; i<256; i++) {
if (found)
break;
executorService.execute(tryNextIp);
}
executorService.shutdown();
try {
while (!found && !executorService.isTerminated())
executorService.awaitTermination(200, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {}
if (found)
return ip;
else
return null;
}
答案 1 :(得分:0)
根据典型的网络条件和服务器响应时间,良好的超时值是您愿意等待服务器回复的时间。您需要选择一个合理的值,与您的应用程序无关 - 由您决定如果服务器在X时间内没有响应,那么可以安全地假设它不在那里。
要加速客户端,请考虑创建多个线程以一次查询多个服务器。 Executors.newFixedThreadPool()
会让你感到琐碎。
但是,您可能需要考虑其他不需要完整网络扫描的替代方案;例如:
让用户/管理员指定IP地址(为什么你需要发现服务器IP?你不知道你设置服务器的机器吗?为什么不呢?配置服务器有静态LAN IP?)
如果您确实需要服务发现,NSD / Zeroconf / Bonjour等技术可以进行服务广告和发现。
即使是非常基本的东西也可能适合您的需求,例如:从客户端发送广播UDP数据包,让服务器响应,或让服务器定期广播通知。
答案 2 :(得分:0)
套接字超时应该完全取决于请求的预期服务时间。天真地你可以找到平均服务时间并使用双倍超时。如果你想要更准确,你需要绘制服务时间的统计分布,确定标准偏差,并使用平均值加上标准差的三倍甚至四倍作为超时,以确保你没有得到假阳性超时但您确实在合理的时间内检测到了失败。最终,这取决于你想要的触发快乐程度。