我有一个项目,我必须在该项目中构建一个多个服务器之间相互通信以响应客户端的系统。
我可以使客户端与服务器通信,但是在使服务器启动它们之间的连接时遇到问题。
在下面的代码中,您可以看到我有一个包含所有服务器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);
}
}
问题是服务器需要尝试与其他服务器连接并等待来自其他服务器的连接。并且在接收到新的连接后,它需要停止尝试连接到对应的服务器,或者如果该服务器尝试与另一台服务器成功连接,则需要停止从该服务器接收新的连接。
关于如何使用套接字实现此的任何建议?
答案 0 :(得分:1)
似乎您尝试分步执行此操作,首先所有服务器尝试连接到其他服务器,但是还没有服务器开始接受连接。在clientSocket连接到服务器之后,您便开始接受连接。听起来这可能导致死锁。
您知道每个服务器都必须接受来自其他服务器的连接。您还知道每个服务器都需要启动与其他服务器的连接。
您必须在两个不同的线程中接受连接和已启动的连接,或者应该使用异步/事件驱动的模型并管理事件循环。
在接收到新的连接后,它需要停止尝试连接到对应的服务器,或者如果该服务器尝试与另一台服务器成功连接,则它需要停止从该服务器接收新的连接。
在这里您想避免比赛。如果每个服务器在尝试连接到其他服务器之前等待X次,这是最容易做到的。这个X应该是启动后的随机延迟。例如。服务器A等待5秒钟才连接,服务器B等待1秒钟,服务器C等待13秒钟才进行连接。但是服务器B和C将不会发起任何连接,因为服务器A已经与这些服务器建立了连接。