[英]java: Good socket timeout for LAN connections?
我有一台服务器(在我的笔记本电脑上运行的Java应用程序)和一个客户端(在我的Android智能手机上运行的Java应用程序 我正在尝试从我的客户端自动查找服务器的IP地址 。
现在我只是循环所有IP在同一个局域网(192.168.1.0> 192.168.1.1.255),如果服务器(正在监听自定义端口)接受连接,那么我找到了IP。
问题是,如果我设置连接超时少于200毫秒,大多数时候客户端找不到服务器。
所以问题是,我如何实现更好(更快)的方式来查找服务器IP? 我尝试过java InetAddress.isReachable()方法,但服务器似乎总是无法访问...
并且,如果没有更好的方法,您认为本地(LAN)套接字连接的超时值是多少?
只是为了其他人...我刚刚找到了一个非常好的方法来找到服务器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;
}
考虑到典型的网络条件和服务器响应时间,良好的超时值是您愿意等待服务器回复的时间。 您需要选择一个合理的值,与您的应用程序无关 - 由您决定如果服务器在X时间内没有响应,那么可以安全地假设它不在那里。
要加速客户端,请考虑创建多个线程以一次查询多个服务器。 Executors.newFixedThreadPool()
会让你无所适从。
但是,您可能需要考虑其他不需要完整网络扫描的替代方案; 例如:
只需让用户/管理员指定IP地址( 为什么需要发现服务器IP?你不知道你在服务器上设置了什么机器?为什么不将服务器配置为具有静态LAN IP?)
如果您确实需要服务发现,NSD / Zeroconf / Bonjour等技术可以进行服务广告和发现。
即使是非常基本的东西也可能适合您的需求,例如从客户端发送广播UDP数据包并让服务器响应,或让服务器定期广播通知。
套接字超时应该完全取决于请求的预期服务时间。 天真地你可以找到平均服务时间并使用双倍超时。 如果你想要更准确,你需要绘制服务时间的统计分布,确定标准偏差,并使用平均值加上标准差的三倍甚至四倍作为超时,以确保你没有得到假阳性超时但您确实在合理的时间内检测到了失败。 最终,它取决于你想要的触发快乐程度。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.