【问题标题】:java: Good socket timeout for LAN connections?java:LAN 连接的良好套接字超时?
【发布时间】:2014-05-04 00:44:41
【问题描述】:

我有一个服务器(在我的笔记本电脑上运行的 java 应用程序)和一个客户端(在我的 android 智能手机上运行的 java 应用程序)。 我正在尝试从我的客户端自动查找服务器的 IP 地址

现在我只是循环同一 LAN (192.168.1.0 > 192.168.1.1.255) 中的所有 IP,如果服务器(正在侦听自定义端口)接受连接,那么我找到了 IP。

问题是,如果我将连接超时设置为小于 200 毫秒,大多数情况下客户端都找不到服务器。

所以问题是,我如何实现更好(更快)的方式来查找服务器 IP? 我尝试过 java InetAddress.isReachable() 方法,但服务器似乎总是无法访问...

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

【问题讨论】:

标签: java android sockets timeout


【解决方案1】:

只为其他人...我刚刚找到了一个非常好的方法,可以在不到半秒内找到服务器 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;
}

【讨论】:

    【解决方案2】:

    考虑到典型的网络条件和服务器响应时间,一个好的超时值是您愿意等待服务器回复的时间。您需要选择一个合理的值,与您的应用程序无关——由您决定如果服务器在 X 时间内没有响应,那么可以安全地假设它不存在。

    为了加快您的客户端速度,请考虑创建多个线程来一次查询多个服务器。 Executors.newFixedThreadPool() 会让你轻松搞定。

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

    • 只需让用户/管理员指定 IP 地址(为什么您需要发现服务器 IP?您不知道您在哪台机器上设置服务器?为什么不直接将服务器配置为具有静态 LAN IP?)

    • 如果您确实需要服务发现,NSD/Zeroconf/Bonjour 等技术可以实现服务广告和发现。

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

    【讨论】:

    • 非常感谢您的回复!我认为满足我的需求最好的解决方案是一次查询多个服务器!我将搜索有关线程池的更多信息,再次感谢!
    • @user2104749 你会发现线程池解决方案非常简单。查看ExecutorService;在创建一个固定的线程池执行器之后,您实际上为每个服务器查询创建了一个RunnableCallable,将它们全部放入队列中,然后等待它们完成。更高的最大线程数 = 可能更快的完成扫描但更高的资源使用率;你会想要找到一个平衡点。
    • 伙计,我刚试了一下,速度非常快!难以置信 :D 我可以在不到 2 秒的时间内找到服务器 ip,非常感谢!
    • 最后一个问题...您认为在 android 设备中将最大线程数设置为 255(每个线程只需打开一个套接字并读取响应)是否安全,或者处理的工作量太大智能手机?
    【解决方案3】:

    socket 超时应该是多少完全取决于请求的预期服务时间。天真地,您可以找到平均服务时间并使用两倍的超时时间。如果你想更准确,你需要绘制服务时间的统计分布,确定标准偏差,并使用平均值加上标准偏差的三甚至四倍作为超时,以确保你没有得到误报超时,但您确实在合理的时间内检测到故障。归根结底,这取决于你想要有多快乐。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-11
      • 1970-01-01
      • 2012-11-17
      • 2011-02-05
      • 2018-11-26
      • 2020-06-02
      • 2016-10-02
      相关资源
      最近更新 更多