Java 创建新套接字时添加超时

Java 创建新套接字时添加超时,java,Java,我有一个带有DHCP的本地网络和几台电脑。其中一台应该是我的服务器,并自动连接到所有其他(客户端)。我的想法是: 首先,我在每个正在从服务器(SClient)侦听客户端程序的客户端(CServer)上创建一个服务器。当SClient连接到CServer时,SClient会向CServer发送他的IP,这样他就知道该IP上将有该服务器。然后,在尝试了其IP范围内的所有IP(例如192.168.1.xxx)后,他启动真正的服务器,所有客户端都连接到已知的服务器IP。 但是,当我尝试以下操作时,当尝试

我有一个带有DHCP的本地网络和几台电脑。其中一台应该是我的服务器,并自动连接到所有其他(客户端)。我的想法是: 首先,我在每个正在从服务器(SClient)侦听客户端程序的客户端(CServer)上创建一个服务器。当SClient连接到CServer时,SClient会向CServer发送他的IP,这样他就知道该IP上将有该服务器。然后,在尝试了其IP范围内的所有IP(例如192.168.1.xxx)后,他启动真正的服务器,所有客户端都连接到已知的服务器IP。 但是,当我尝试以下操作时,当尝试连接到192.168.1.0时,SClient在第一个IP上冻结。我如何定义一个超时或类似的东西,让客户端放弃不成功的连接并继续使用192.168.1.1

import java.lang.*;
import java.io.*;
import java.net.*;

class SClient {
    public SClient() {
        for(int i = 120; i < 125; i++){
            try{
                InetAddress addr = InetAddress.getLocalHost();
                String addrs = addr+"";
                String ip = addrs.substring(addrs.indexOf("/")+1);
                Socket s1 = new Socket("192.168.1." + i, 1254);

                OutputStream s1out = s1.getOutputStream();
                DataOutputStream dos = new DataOutputStream (s1out);
                dos.writeUTF(ip);
                dos.close();
                s1out.close();
                s1.close();
            }catch(IOException e){}
        }
    }
}

}

使用UDP更容易做到这一点。一般逻辑是:

  • 确定“发现”的已知端口
  • 任何启动的机器都会发送“查询主服务器”消息
  • 如果在一个时间范围内没有收到对该消息的响应 您定义,然后发送它的机器自动指定 将其自身作为服务器
  • 此后,任何发送“查询主服务器”的机器 消息将从主机返回一个响应,带有它的IP地址 地址和“通信端口”
  • 通过通信端口将新机器连接到服务器 然后开始发送消息

  • 在这种情况下,您可能会遇到多台服务器认为它是主服务器的情况,然后您需要一个冲突解决过程,但大纲应该能让您大致了解适合您的过程。

    我找到了解决问题的方法。它只是初始化套接字,而不是使用

    Socket s1 = new Socket("192.168.1." + i, 1254);
    
    但是

    Socket s1 = new Socket();
    s1.setSoTimeout(200);
    s1.connect(new InetSocketAddress("192.168.1." + i, 1254), 200);
    

    无论如何谢谢你

    您需要进行多播并考虑竞争条件。是的,他确实需要使用多播。你也提到了什么比赛条件?两台机器相隔几秒钟就出现了,两台机器都发出一个主设备的查询,但都没有找到主设备(两台都还不是主设备)。每个人都称自己为主人。你现在有2个大师。我想您可以通过首先打开多播端口并使用确定性、绝对性和传递性选择算法来处理两个(或更多)主节点问题来解决这个问题。现有主版本与新主版本的对比情况如何?这有点头疼,特别是因为最初的问题是关于一个场景,有一个主机和很多客户端(都在DHCP上)。是的,这是我提到的冲突解决过程,但没有概述。这主要是因为它是一个令人头痛的问题——事实上,它往往是分布式、动态服务器协议中最复杂的部分。一个简单的投票过程包括在竞争的服务器之间发送数据包以及它们的启动时间。所有启动时间较短的服务器都会将自己重新指定为常规客户端。没错,这是一个合理的算法。也可能在启动时生成一个UUID来打破僵局。这可能是因为您从192.168.1.0开始。如果我没记错的话,IP地址永远不会以0结尾,只有子网掩码会。试着从1开始,看看是否效果更好。如果它是一个不存在的IP,它应该会很快超时。在这种情况下,我从192.168.1.120开始,因为我知道我在123有一个存在的IP,但它不会超时。如果这解决了你的问题,那么接受你自己的答案。你不会因此得到任何分数(当然!),但这有助于其他人阅读这个问题,因为他们知道这是解决方案。我想接受我自己的答案,但我不得不再等16个小时。那我就做。
    Socket s1 = new Socket();
    s1.setSoTimeout(200);
    s1.connect(new InetSocketAddress("192.168.1." + i, 1254), 200);