2014-03-25 21 views
1

我有一个服务器(我的笔记本电脑上运行的Java应用程序)和一个客户端(我的android智能手机上运行的Java应用程序)。 我想从自动找到服务器的IP地址java:良好的LAN连接套接字超时?

现在我只是将所有的IP都放在同一个局域网(192.168.1.0> 192.168.1.1.255),并且如果服务器(即在自定义端口上监听)接受连接,那么我找到了IP。

问题是,如果我设置连接超时少于200毫秒,客户端找不到服务器的次数最多。

所以问题是,我如何实现更好(更快)的方式来找到服务器IP? 我已经尝试了java InetAddress.isReachable()方法,但服务器总是看起来不可取...

而且,如果没有更好的方法,您认为这是一个很好的本地(LAN)超时值,套接字连接?

+0

你可能想看看网络服务发现 - http://developer.android.com/training/connect-devices-wirelessly/nsd.html或类似的东西。 –

回答

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; 
} 
0

给定的网络条件和服务器响应时间,一个很好的超时值是你愿意等待服务器回复的时间。您需要选择一个合理的值,与您的应用程序无关 - 这取决于您决定如果服务器在X时间内没有响应,那么假定它不在那里是安全的。

为了加速您的客户端,请考虑创建多个线程来一次查询多个服务器。 Executors.newFixedThreadPool()会为你做这个小事。

但是,您可能想要考虑其他不需要全面网络扫描的替代方案;例如:??

  • 只是让用户/管理员指定的IP地址(为什么你需要发现服务器IP难道你不知道你设置什么机器在您的服务器为什么不直接配置服务器拥有一个静态局域网IP?)

  • 如果您确实需要服务发现,像NSD/Zeroconf/Bonjour这样的技术允许进行服务广告和发现。

  • 即使是非常基本的东西也可能适合您的需求,例如,从客户端发送广播UDP数据包并让服务器响应,或让服务器定期广播通知。

+1

非常感谢您的回复!我认为**符合我的需求**最好的解决方案是一次查询多个服务器!我将搜索更多关于threadpool的信息,再次感谢! – Suxsem

+0

@ user2104749然后,您会发现该线程池解决方案非常简单。查看['ExecutorService'](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html);在创建一个固定的线程池执行程序之后,您基本上会为每个服务器查询创建一个'Runnable'或'Callable',将它们全部放入队列中,并等待它们完成。更高的最大线程数=可能更快的完整扫描,但资源使用率更高;你会想找到一个平衡。 –

+1

我刚刚尝试过它,这是快速的!令人难以置信:D我可以在2秒内找到服务器IP,非常感谢! – Suxsem

0

什么套接字超时应在请求的预期服务时间完全取决于。天真地,你可以找到平均的服务时间,并使用双倍超时。如果你想得到更准确的结果,你需要绘制服务时间的统计分布,确定标准偏差,并使用平均值加上标准偏差的三倍甚至四倍作为超时,以确保你没有得到假阳性超时,但您在合理的时间内检测到故障。最终它取决于你想成为怎样的触发器。