Java动态查找局域网内其他主机

发布于 2024-09-06 06:56:08 字数 1414 浏览 12 评论 0原文

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

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

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

一开始只有几个主机,因此这个 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 值较低(500ms)时,我得到错误的 Host Not Found 状态 for主机实际活跃。
  • CONNECTION_TIME_OUT 值较高(5000 毫秒),并且只有一个线程需要永远结束。
  • 对于多个线程,我也发现了与第一个线程类似的问题,原因是冲突。

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

A while ago I developed a little LAN chat app. in Java which allows chatting with other hosts, send images, etc. Although it was created just for fun, now it's being used where I work.

Currently, there is no "chat server" on the app. where each client registers, updates it's status, etc. (I liked the idea of symmetric design and not depending on a server running on some other machine).

Instead, each host is a client/server which has a hosts.properties file with the hostname of the other hosts, and - for instance - broadcasts to each one of them when sending a massive message/image/whatever.

In the beginning there were just a couple of hosts, so this hosts.properties file wasn't an issue. But as the amount of users increased, the need of updating that file was a bit daunting. So now I've decided to get rid of it, and each time the app. starts, dynammically find the other active hosts.

However, I cannot find the correct way of implement this. I've tried starting different threads, each one of them searching for other hosts in a known range of IP addresses. Something like this (simplified for the sake of readability):

/** 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!
}

However:

  • With a single thread and a low value in CONNECTION_TIME_OUT (500ms) I get wrong Host Not Found status for for hosts actually active.
  • With a high value in CONNECTION_TIME_OUT (5000ms) and only one single thread takes forever to end
  • With several threads I've also found problems similar like the first one, due to collisions.

So... I guess there's a better way of solving this problem but I couldn't find it. Any advice? Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

败给现实 2024-09-13 06:56:08

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

You could try UDP Broadcast to a specific port. All running instances of your app on the network could listen to that port and then respond with a message identifying them as a host.

心的位置 2024-09-13 06:56:08

您可以使用 UDP 更轻松地完成此操作。 查看本教程以获取示例。

You could do this a lot easier using UDP. Check this tutorial for examples.

与他有关 2024-09-13 06:56:08

使用 Bonjour/Zeroconf。

jmdns 项目 拥有您所需的一切。

Use Bonjour/Zeroconf.

The jmdns project has all you need.

无可置疑 2024-09-13 06:56:08

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

下面是一些小代码,将帮助您在Windows中读取局域网中的所有主机,还有其他命令用于其他os看看下面的代码

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();
    }

For finding all hosts in lan in java execute commands from java and add the result to JList

Here is the small code that will help to you to read all hosts in lan in windows there will be other commands for other os take look at the following code

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();
    }
死开点丶别碍眼 2024-09-13 06:56:08

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

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

这样

a) 无需网络扫描
b) 一个新的主机将在网络中传播

然后当一个新的主机加入时,他只需要认识另外一台主机就可以了解每个人。

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

Each host keeps track of all the hosts they have met. When you shut down, save the known hosts to file and reuse the next time you start up.

Every so many minutes, send each of the known hosts a list of all known hosts.

That way

a) No network scanning
b) A new host will spread around the network

Then when a new host joins, he just needs to know 1 other host to learn about everyone.

A host that isn't seen for a week, or is seen from a new IP is dropped from the list of updated.

初雪 2024-09-13 06:56:08

使用 DNS 服务发现

您可以尝试 成为 sourceforge 上的一个项目(除了粗略搜索之外,我还没有看过......)

You could attempt to use DNS service discovery

There seems to be a project on sourceforge (that I have not looked at, beyond doing a cursory search...)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文