Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从轮询中的线程连接到远程端口(服务器)_Java_Sockets_Exception Handling_Thread Safety_Serversocket - Fatal编程技术网

Java 从轮询中的线程连接到远程端口(服务器)

Java 从轮询中的线程连接到远程端口(服务器),java,sockets,exception-handling,thread-safety,serversocket,Java,Sockets,Exception Handling,Thread Safety,Serversocket,我想从线程连接到远程服务器并继续发送字符串。如果连接被拒绝,线程应该继续轮询端口,直到服务器再次启动。如何处理此异常并防止线程崩溃?服务器可能长时间未启动,但线程应无限期运行 public void SendMessage(String message){ try { socket = new Socket(actuatorAddress, destPort.get()); outToServer = socket.getOutputStream();

我想从线程连接到远程服务器并继续发送字符串。如果连接被拒绝,线程应该继续轮询端口,直到服务器再次启动。如何处理此异常并防止线程崩溃?服务器可能长时间未启动,但线程应无限期运行

public void SendMessage(String message){
    try {
        socket = new Socket(actuatorAddress, destPort.get());
        outToServer = socket.getOutputStream();
        out = new DataOutputStream(outToServer);
        out.flush();
        out.write(message.getBytes());
    } catch (IOException ex) {
        System.out.println(ex.getMessage());
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }
}
我更改了代码的某些部分,如下所示。第一次调用连接函数,然后通过线程调用发送消息函数。重新连接增加的延迟有助于减少由于连接到不存在的服务器而再次出现的时间延迟。我仍然认为可能有更好的办法来解决这个基本问题

public boolean ConnectToActuator() {
    try {
        if(actuatorAddress.isReachable(2000)){
            socket = new Socket();
            socket.setPerformancePreferences(1, 2, 0);
            socket.setTcpNoDelay(false);
            socket.setSendBufferSize(32);
            socket.connect(new InetSocketAddress(actuatorAddress, destPort.get()));
            outToServer = socket.getOutputStream();
            out = new DataOutputStream(outToServer);
            connected = true;
            disconnectedTimeout = 0;
        }
    }catch (ConnectException e) {
        // TODO Auto-generated catch block
        System.out.println(e.getMessage());
    }catch (IOException ex) {
        connected = false;
        System.out.println(ex.getMessage());
    }
    return connected;
}

public boolean SendToActuator(String message) {
    if(connected == false){ //socket.isOutputShutdown()
        disconnectedTimeout++;
        if(disconnectedTimeout>20){
            disconnectedTimeout = 0;
            ConnectToActuator();
        } else {
            return connected;
        }
    }
    try {
        out.flush();
        out.writeBytes(message);
        disconnectedTimeout = 0;
        connected = true;
    } catch (UnknownHostException uhe) {
        connected = false;
        System.out.println(uhe.getMessage());
    } catch (IOException ioe) {
        connected = false;
        System.out.println(ioe.getMessage());
    }
    return connected;
}
伪:

while(true){
  if(connect()) DoClientConnectedStuff();
  sleep(reconnectTimeout);
};

请尝试以下更改。如果您的连接被拒绝,它将等待2秒(2000毫秒),然后再次尝试连接服务器。如果连接成功,则需要outputstream,在while循环中写入数据并刷新数据

public void createSocketConnection() throws IOException
{     
    socket = new Socket(actuatorAddress, destPort.get());
    if(socket!=null)
        {
          outToServer = socket.getOutputStream();
          out = new DataOutputStream(outToServer);
        }

}

public void SendMessage(String message){
    boolean isRunning=false;
    try 
    {
        createSocketConnection();
        isRunning=true;
        while(isRunning)
        {
          out.write(message.getBytes());
          out.flush();
       }
    } catch (java.net.ConnectException conExcp) {
        System.out.println(ex.getMessage());
        try{
          Thread.sleep(2000);
        }catch(Exception ee){}
    } 
    catch (IOException ex) {
        System.out.println(ex.getMessage());

    } 
}

鉴于评论中的以下限制:

  • 尝试将消息发送到10台服务器之一
  • 如果没有任何服务器可用于接收该消息,请丢弃该消息
你真正想做的是:

  • 遍历服务器地址列表
  • 尝试向他们每个人发送消息
  • 如果成功,立即跳出循环
  • 捕获连接失败时的任何错误,然后尝试下一个服务器
  • 下面是一个将在该场景中运行的示例类

    import java.io.DataOutputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    
    public class MessageSender {
      private static final Integer destPort = 1234;
    
      private static final String[] serverAddresses = {
        "address1",
        "address2",
        "address3" // Etc....
      };
    
      public Boolean SendMessage(String message) {
        Boolean messageSentSuccessfully = false;
        for (String addy : serverAddresses) {
          messageSentSuccessfully = SendMessageToServer(addy, message);
          if (messageSentSuccessfully) {
            break;
          }
        }
        return messageSentSuccessfully;
      }
    
      private Boolean SendMessageToServer(String serverAddress, String message) {
        Boolean messageSent = false;
        try {
          Socket dataSocket = new Socket(serverAddress, destPort);
          OutputStream outToServer = dataSocket.getOutputStream();
          DataOutputStream out = new DataOutputStream(outToServer);
          out.write(message.getBytes());
          out.flush();
          messageSent = true;
        } catch (Exception e) {
          System.out.println(e);
        }
        return messageSent;
      }
    }
    

    希望这能有所帮助。

    你所说的“长时间”是什么意思?另外,您的代码的目标是什么:您是在尝试测试服务是否启动,还是100%确保消息最终会被发送,即使您不知道服务何时可用?只要偶尔有一些信息通过,你会在意这些信息是否会丢失吗?或者你需要确保它们都被接收到了吗?目标是网络中大约有10台服务器连接在一起,从这个线程读取消息。服务器可能会断开连接几分钟甚至几个小时,或者可能会从网络中删除。但我仍然希望任务继续运行,并将消息发送到其他已连接的服务器。消息丢失不是问题。基本上我想处理连接被拒绝的异常。如果我能在创建套接字之前检查连接是否会被拒绝,那就更好了。因此,我们的想法是尝试连接到所有服务器,如果没有服务器,您可以丢弃消息?是的。我添加了catch“ConnectException”来处理这个异常,但是它会导致向连接的服务器发送消息的时间延迟。谢谢TreyE。我试图使用InetSocketAddress(actuatorAddress,destPort.get()).getAddress().isReachable(超时)检查远程服务器是否可用,但这只检查远程IP是否可访问,而不检查特定端口是否可访问。问题是,您并不真正关心服务器是否可用,你只是关心你是否能发送信息。因此,您不妨尝试发送消息。在测试时,“socket”不可能为null。你没有花插座的钱。此代码不会重试任何操作-1.