java - 从轮询线程连接到远程端口(服务器)

标签 java sockets exception thread-safety serversocket

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

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

我更改了部分代码,如下所示。第一次调用 Connect 函数,然后通过线程调用 Send Message 函数。重新连接所增加的延迟有助于减少由于连接到不存在的服务器而再次出现的时间延迟。仍然认为可能有更好的解决基本问题的方法。

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

最佳答案

考虑到评论中的以下限制:

  • 尝试将消息发送到 10 台服务器之一。
  • 如果没有服务器可以接收该消息,则丢弃该消息。

你真正想做的是:

  1. 迭代服务器地址列表
  2. 尝试向每个人发送消息
  3. 如果成功则立即跳出循环
  4. 捕获连接失败时的任何错误并尝试下一个服务器

这是一个将在该场景中运行的示例类。

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

希望有帮助。

关于java - 从轮询线程连接到远程端口(服务器),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21339342/

相关文章:

java - java可以只使用ReentrantLock来保证非违反变量在线程中可见吗

python - python 中的多人服务器套接字

.net - LINQ 和 .COUNT 超时

java - JAR 内的 Apache Camel JSch privateKeyFile

c# - 空间坐标的 3D 数组

java - 即使应用程序崩溃后,IPV6 ServerSocket 仍在监听

python - 为什么我不能在 Python 中接收 UDP 数据包?

java - 烟灰、身份 stmts 和异常处理期间的控制流

java - 处理持久性异常

java - Libgdx scene2d uiskin.json com.badlogic.gdx.utils.GdxRuntimeException