客户端程序是否可以有服务器套接字与其他客户端程序通信



我正在尝试实现一个多线程套接字程序,该程序模拟五台计算机和一个控制器通过套接字相互通信。控制器有一个接受传入套接字(来自计算机(的服务器套接字。一旦它达到系统的最大容量(比如说五个(,它就会向那些使用在接受传入套接字时创建的线程的计算机发送一条启动消息。

当每台计算机都从控制器接收到"开始"消息时,我希望每台计算机能够与其他计算机通信(而不依赖控制器(将消息从计算机中继到控制器再中继到计算机(。我认为可行的方法是让每台计算机实例化一个服务器套接字,这样它就可以接受来自计算机的传入套接字。并实例化另一个客户端套接字,以便来自不同计算机的其他服务器套接字可以接受它

我知道这听起来可能很困惑,但基本上我想在每个客户端程序(计算机(上使用一个服务器套接字,这样它就可以在不依赖控制器的情况下监听其他客户端(计算机(。

这可能吗?我可以为每个客户端程序(计算机(实例化一个服务器套接字,以便它可以监听其他计算机吗?它是否需要来自控制器服务器套接字的不同IP地址和/或端口号?我需要为x台计算机实例化x个套接字吗

也许我的Java代码可以理解这一点。

Controller.java

package timetableexchange;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class Controller {
final int MAX_SYSTEMS = 2;
static ArrayList<ServerConnection> conns = new ArrayList<ServerConnection>();   // connections to computer
static int finishedCount = 0;                                                   // number of finished computers
ServerSocket ss;            // server socket
public static void main(String[] args) throws IOException {
// Instantiate controller
new Controller(8000);
}
public Controller(int port) throws IOException {
// Instantiate server socket
ss = new ServerSocket(8000);
int i = 0;
// Listen and accept clients (1 for testing)
while (i < MAX_SYSTEMS) {
Socket s = ss.accept();
// add to list
ServerConnection conn = new ServerConnection(i++, s);
conns.add(conn);
}
// start server connection thread
for (i = 0; i < conns.size(); ++i) {
conns.get(i).start();
}
ss.close();
}
// Thread for communicating between controller and computer
private class ServerConnection extends Thread {
Socket socket;
BufferedReader in;
PrintWriter out;
int identifier;
// constructor
public ServerConnection(int i, Socket s) throws IOException {
this.identifier = i;
this.socket = s;
this.in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
this.out = new PrintWriter(socket.getOutputStream(), true);
System.out.println("Client Connected");
}
@Override
public void run() {
System.out.println("ServerConnection started");
// send ID to computers
sendAll(identifier + "");
// send Start message to computers
sendAll("Start");
// Check if a computer sent back a Finish message
// If all computers are finished, then send out Tear Down message.
while (true) {
try {
String clientInput = in.readLine();
if (clientInput.equals("Finish")) {
finishedCount += 1;
if (finishedCount == conns.size()) {
sendAll("Tear Down");
}
}
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
private void sendAll(String text) {
for (int i = 0; i < conns.size(); ++i) {
ServerConnection conn = conns.get(i);
conn.out.println(text);
}
}
}
}

计算机.java

package timetableexchange;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Vector;
public class Computer {
final int MAX_SYSTEMS = 2;
int identifier;                                         // Computer ID
int eventCount;                                         // Number of Generated Events
ArrayList<Socket> sockets = new ArrayList<Socket>();    // List of (client) sockets
Vector<Integer> timestamp = new Vector<Integer>();      // Time-stamp vector
Socket socketToServer;                                  // Socket to Connect to Controller
BufferedReader inputFromServer;                         // Input Stream from Controller
PrintWriter outputToServer;                             // Output Stream to Controller
String textFromServer;                                  // String sent from Controller
ServerSocket ss;                                        // Server Socket to communicate with other clients (computers)
Socket socketToClient;                                  // Socket to Connect to Computer
BufferedReader inputFromClient;                         // Input Stream from Computer
PrintWriter outputToClient;                             // Output Stream to Computer
public static void main(String[] args) throws IOException {
// Instantiate Computer
new Computer("127.0.0.1", 8000);
}
// Constructor
public Computer(String hostname, int port) throws IOException {
// Instantiate Socket (to Controller) and Streams (to Controller)
socketToServer = new Socket(hostname, port);
inputFromServer = new BufferedReader(new InputStreamReader(socketToServer.getInputStream()));
outputToServer = new PrintWriter(socketToServer.getOutputStream(), true);
// Check if Controller sent the computer its ID
while (true) {
try {
textFromServer = inputFromServer.readLine();
// set identifier
identifier = Integer.parseInt(textFromServer);
System.out.println(identifier);
break;  // break loop
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
// Check if Controller sent the start message
while (true) {
textFromServer = inputFromServer.readLine();
if (textFromServer.equals("Start"))
System.out.println("Start message received");
break;  // break loop
}
// Instantiate Server Socket (for Clients)
ss = new ServerSocket(port + identifier + 1);
// Instantiate Client Socket for Other Clients to Hear
socketToClient = new Socket();
inputFromClient = new BufferedReader(new InputStreamReader(socketToClient.getInputStream()));
outputToClient = new PrintWriter(socketToClient.getOutputStream());
// listen to server socket and add accepted socket to list  
for (int i = 0; i < MAX_SYSTEMS - 1; ++i) {
Socket s = ss.accept();
System.out.println("Client accepted");
sockets.add(s);
}
Thread readEvent = new Thread(new Runnable() {
@Override
public void run() {
/**
* Read from input stream
* Read the vector inside the input stream
* Compare vectors and choose the largest integer (synchronized)
* Add 1 to the corresponding socket. (synchronized)
*/
}
});
Thread writeEvent = new Thread(new Runnable() {
@Override
public void run() {
/**
* Generate random number between 0 and 4.
* If zero, then add 1 to its own socket in vector.
* Else, send vector to random socket via output stream
*/
}
});
readEvent.start();
writeEvent.start();
}
}

我很感激你的帮助!

简而言之:

这可能吗?

是-为什么不呢?

我可以实例化每个客户端程序(计算机(一个服务器套接字吗它可以监听其他电脑?

是的-你可以做任何你想要或需要的

是否需要与控制器的服务器插座?

IP地址属于"物理计算机"/hetwork接口,与您尝试做什么无关-所有这些都可以在一台计算机上运行,并且都可以在同一IP地址上运行(例如127.0.0.1(。您必须为即将打开的每个服务器套接字都有专用端口,并且您的客户端套接字必须知道要与之通信的IP和端口号。对于客户端套接字,您不需要关心IP和端口号。

我需要为x数量的电脑?

这个问题对我来说意义不大——这是你的设计决定,你需要实例化多少个服务器套接字——一个端口一个服务器套接字,就这样。

最新更新