首页 > 解决方案 > Java 服务器使用套接字连接到其他服务器

问题描述

我有一个项目,我必须构建一个系统,其中多个服务器相互通信以响应客户端。

我可以让客户端与服务器通信,但我在让服务器启动它们之间的连接时遇到问题。

在下面的代码中,您可以看到我有一个包含所有服务器 IP 的列表。对于每个 ip,当前服务器尝试与其他服务器连接。您还可以看到服务器正在等待连接,在这种情况下,是来自其他服务器的连接。

@Override
public void run() {
    // Trying to connect with server
    for (String serverIp : servers) {
        System.out.println("Trying to connect with " + serverIp);
        try {
            Socket clientSocket = new Socket(serverIp, this.port);
            this.clientPool.submit(new ClientThread(clientSocket, this.streamHandler));
        } catch (Exception e) {
            System.out.println("Error");
        }
        System.out.println("Connected with " + serverIp);
    }
    // Receiving connections from other servers
    // In these case we call client to the other server
    try (ServerSocket serverSocket = new ServerSocket(port)) {
        System.out.println("Waiting for clients to connect...");
        while (true) {
            Socket clientSocket = serverSocket.accept();
            this.clientPool.submit(new ClientThread(clientSocket, this.streamHandler));
        }
        // serverSocket.close();
    } catch (IOException e) {
        Configuration.printError("Error starting server", e);
    }
}

问题是服务器需要尝试与其他服务器连接并等待来自其他服务器的连接。并且在接收到新连接后,它需要停止尝试连接到对应服务器,或者如果服务器尝试与其他服务器连接成功,则需要停止从该服务器接收新连接。

关于如何用套接字实现这一点的任何建议?

标签: javamultithreadingsocketsdistributed-systemraft

解决方案


似乎您尝试分步执行此操作,首先所有服务器都尝试连接到其他服务器,但还没有服务器开始接受连接。在 clientSocket 连接到服务器后,您就开始接受连接。听起来这可能会导致僵局。

您知道每台服务器都必须接受来自其他服务器的连接。您还知道每台服务器都需要启动与其他服务器的连接。

您必须在两个不同的线程中接受连接启动的连接,或者您应该使用异步/事件驱动模型并管理事件循环。

并且在收到新连接后,它需要停止尝试连接到对应服务器,或者如果服务器尝试与其他服务器连接成功,则需要停止从该服务器接收新连接。

在这里,您要避免比赛。如果每个服务器在尝试连接到其他服务器之前等待 X 时间,这是最容易做到的。这个 X 应该是从启动开始的随机延迟。例如,服务器 A 在连接前等待 5 秒,服务器 B 在连接前等待 1 秒,服务器 C 在连接前等待 13 秒。但是服务器 B 和 C 不会发起任何连接,因为服务器 A 已经与这些服务器建立了连接。


推荐阅读