【问题标题】:Dynamically find other hosts in a LAN in JavaJava动态查找局域网中的其他主机
【发布时间】:2010-06-16 01:49:39
【问题描述】:

不久前,我开发了一个小型局域网聊天应用程序。在 Java 中,它允许与其他主机聊天、发送图像等。虽然它只是为了好玩而创建的,但现在它正在我工作的地方使用。

目前,应用上没有“聊天服务器”。每个客户端在哪里注册,更新它的状态等(我喜欢对称设计的想法,而不是依赖于在其他机器上运行的服务器)。

相反,每个主机都是一个客户端/服务器,它有一个 hosts.properties 文件,其中包含其他主机的主机名,并且 - 例如 - 在发送大量消息时向每个主机广播/image/随便。

一开始只有几个主机,所以这个 hosts.properties 文件不是问题。但是随着用户数量的增加,更新该文件的需求有点令人生畏。所以现在我决定摆脱它,每次应用程序。启动,动态查找其他活动主机。

但是,我找不到正确的实现方法。我尝试过启动不同的线程,每个线程都在已知 IP 地址范围内搜索其他主机。像这样的东西(为了可读性而简化):

/** HostsLocator */
public static void searchForHosts(boolean waitToEnd) {
    for (int i=0; i < MAX_IP; i+= MAX_IP / threads) {
        HostsLocator detector = new HostsLocator(i, i+(MAX_IP / threads - 1)); // range: from - to
        new Thread(detector).start();                 
    }
}

public void run() {
    for (int i=from; i<=to; i++)
        findHosts( maskAddress + Integer.toString(i) );
}

public static boolean findHosts(String IP) {
    InetAddress address = InetAddress.getByName(IP);
    if ( address.isReachable(CONNECTION_TIME_OUT) )
        // host found!
}

但是:

  • 对于单个线程和 CONNECTION_TIME_OUT(500 毫秒)中的低值,对于实际处于活动状态的主机,我得到错误的 Host Not Found 状态。
  • CONNECTION_TIME_OUT (5000ms) 的值很高,并且只有一个线程需要永远结束
  • 由于冲突,我还发现了与第一个线程类似的问题。

所以...我想有更好的方法来解决这个问题,但我找不到。有什么建议吗?谢谢!

【问题讨论】:

标签: java networking chat


【解决方案1】:

您可以尝试将 UDP 广播到特定端口。网络上所有正在运行的应用程序实例都可以侦听该端口,然后以将它们标识为主机的消息进行响应。

【讨论】:

  • +1 - 这大致类似于 ARP 协议的工作原理。
  • 广播的问题是另一个程序或服务可能在程序将要监听的端口上运行。
【解决方案2】:

您可以使用UDP 更轻松地做到这一点。例如Check this tutorial

【讨论】:

    【解决方案3】:

    使用 Bonjour/Zeroconf。

    The jmdns project 拥有您所需要的一切。

    【讨论】:

      【解决方案4】:

      为了在java中查找局域网中的所有主机,从java执行命令并将结果添加到JList

      这是一个小代码,可以帮助你在windows中读取局域网中的所有主机,其他操作系统的其他命令看看下面的代码

      try {
      
          Runtime rt = Runtime.getRuntime();
          FileWriter write=new FileWriter("mylist.txt");
          BufferedWriter writer=new BufferedWriter(write);
          Process pr = rt.exec("net view");
      
          BufferedReader input = new BufferedReader(new InputStreamReader(pr.getInputStream()));
      
          String line=null;
          String hosts="";
          while((line=input.readLine()) != null) {
              Thread.sleep(100);
              if((!(line.equals("")))&&(!(line.equalsIgnoreCase("Server Name            Remark")))&&(!(line.equalsIgnoreCase("-------------------------------------------------------------------------------")))&&(!(line.equalsIgnoreCase("The command completed successfully.")))) 
              {
                  line=line.replace('\\',' ');
                  line=line.trim();
                  listModel.addElement(line);
                  hosts=hosts+line.trim()+",";
                  hosts=hosts.trim();
              }
          }
          writer.write(hosts);
          writer.close();
          } catch(Exception e) {
              System.out.println(e.toString());
              e.printStackTrace();
          }
      

      【讨论】:

        【解决方案5】:

        每个主机都会跟踪他们遇到的所有主机。关闭时,将已知主机保存到文件中,并在下次启动时重复使用。

        每隔几分钟,向每个已知主机发送所有已知主机的列表。

        这样

        a) 无网络扫描
        b) 一个新的主机将遍布网络

        那么当一个新的主机加入时,他只需要知道另外一个主机就可以了解每个人。

        一周未见的主机或从新 IP 可见的主机将从更新列表中删除。

        【讨论】:

          【解决方案6】:

          您可以尝试使用DNS service discovery

          似乎有一个项目on sourceforge(我没有看过,除了粗略搜索......)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-01-28
            • 2017-04-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-09-09
            相关资源
            最近更新 更多