Java TCP服务器无法从多个客户端接收消息

我想做最简单的解释。 我的Java TCP项目有一个服务器和三个客户端。

服务器有一个ClientThread。 每个客户端都有一个ServerThread和一个UserThread。

工作流程是:
1.客户端的UserThread(例如,client_0)获取用户输入,然后向服务器发送消息。
2.服务器的ClientThread从client_0捕获消息,并将另一条消息发送到另一个客户端(例如client_1)的ServerThread。
3.然后client_1的ServerThread将另一条消息发送回服务器中运行的ClientThread;

步骤3的消息未到达服务器。

总共有3个客户端,比如client_0,client_1和client_2。
最初的想法是,如果client_0请求服务器,则服务器与client_1和client_2通信。 这就是为什么行if(i==cid) continue; 在服务器的for循环中。 但是,如果我注释掉这一行,服务器会与client_0进行通信(这在语义上是不必要的),并且不会发生消息传递问题。 之后,服务器与client_1进行通信,然后再次出现问题。

服务器可以从客户端(client_0)的ServerThread接收消息,该消息从其UserThread发送原始请求( msgToServer.println("get list"); )以启动整个过程。 但是服务器无法从任何其他客户端的ServerThread获取消息,即使它可以向其他客户端发送消息,并且所有客户端程序都是相同的,并且所有ServerThreads和UserThreads都应该起作用。 怎么可能呢?

服务器:

 package serverftp; import java.io.*; import java.net.*; public class ServerFTP { static String[] id = {"cp 1","cp 2","cp 3"}; static String[] pass = {"123","456","789"}; static BufferedReader[] msgFromClient = new BufferedReader[3]; static PrintWriter[] msgToClient = new PrintWriter[3]; static InputStream[] fileFromClient = new InputStream[3]; static OutputStream[] fileToClient = new OutputStream[3]; public static void main(String[] args) throws Exception { ServerSocket welcome = new ServerSocket(6789); // connecting the three clients for(int i=0; i<3; i++) { System.out.println("Waiting for Client "+i); Socket clientSocket; clientSocket = welcome.accept(); while(true) { System.out.println("Connecting Client "+i); BufferedReader fromClient = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); PrintWriter toClient = new PrintWriter(clientSocket.getOutputStream(),true); // get id pass from client String clientId = fromClient.readLine(); System.out.println(clientId); String clientPass = fromClient.readLine(); System.out.println(clientPass); // check id pass and feedback if(clientId.equals(id[i]) && clientPass.equals(pass[i])) { toClient.println("ok"); msgFromClient[i] = fromClient; msgToClient[i] = toClient; fileFromClient[i] = clientSocket.getInputStream(); fileToClient[i] = clientSocket.getOutputStream(); break; } else { toClient.println("error"); } } ClientThread ct = new ClientThread(i); ct.start(); System.out.println("Client "+i+" connected!"); } welcome.close(); } } class ClientThread extends Thread { int cid; String msg; public ClientThread(int client_id) { cid = client_id; try { // telling client it's serial ServerFTP.msgToClient[cid].println(Integer.toString(cid)); } catch(Exception ex) { ex.printStackTrace(); } } @Override public void run() { while(true) { try { // get request from receiver msg = ServerFTP.msgFromClient[cid].readLine(); if(msg.equals("get list")) { System.out.println(cid+" "+msg); msg = ServerFTP.msgFromClient[cid].readLine(); System.out.println(cid+" "+msg); for(int i=0; i<3; i++) { if(i==cid) continue; // send sender request for file list ServerFTP.msgToClient[i].println("give list"); System.out.println("request sent to client "+i); // get file count from sender msg = ServerFTP.msgFromClient[i].readLine(); System.out.println("file count caught!!!"); // THIS LINE NEVER EXECUTES System.out.println("File count "+msg); } } } catch(Exception ex) { ex.printStackTrace(); } } } } 

System.out.println("file count caught!!!");System.out.println("file count caught!!!"); 永远不会被称为。

客户:

 package clientftp_1; import java.io.*; import java.net.*; public class ClientFTP_1 { static String[] allPaths = { "...path...\\client_1_folder", "...path...\\client_2_folder", "...path...\\client_3_folder"}; public static void main(String[] args) throws Exception { InetAddress inetAddress = InetAddress.getLocalHost(); Socket server = new Socket(inetAddress,6789); int myId; // login phase BufferedReader fromUser = new BufferedReader(new InputStreamReader(System.in)); BufferedReader fromServer = new BufferedReader(new InputStreamReader(server.getInputStream())); PrintWriter toServer = new PrintWriter(server.getOutputStream(),true); InputStream getFile = server.getInputStream(); OutputStream sendFile = server.getOutputStream(); while(true) { System.out.println("id: "); String msg = fromUser.readLine(); toServer.println(msg); System.out.println("password: "); msg = fromUser.readLine(); toServer.println(msg); msg = fromServer.readLine(); if(msg.equals("ok")) { System.out.println("Connection Successful!"); myId = Integer.parseInt(fromServer.readLine()); System.out.println("Client serial is: "+myId); System.out.println("Folder path is: "+allPaths[myId]); break; } else { System.out.println("Error! Try again please."); } } ServerThread st = new ServerThread(allPaths[myId],fromUser,fromServer,toServer,getFile,sendFile); st.start(); UserThread ut = new UserThread(allPaths[myId],fromUser,fromServer,toServer,getFile,sendFile); ut.start(); } } class ServerThread extends Thread { String folderPath; String msg; BufferedReader msgFromServer,msgFromUser; PrintWriter msgToServer; InputStream fileFromServer; OutputStream fileToServer; public ServerThread(String path,BufferedReader fromUser,BufferedReader fromServer,PrintWriter toServer,InputStream getFile,OutputStream sendFile) throws Exception { folderPath = path; msgFromUser = fromUser; msgFromServer = fromServer; msgToServer = toServer; fileFromServer = getFile; fileToServer = sendFile; } @Override public void run() { System.out.println("Server Thread Started"); while(true) { try { // receive request msg = msgFromServer.readLine(); System.out.println("request received from server"); if(msg.equals("give list")) { // get filenames File folder = new File(folderPath); File[] fileList = folder.listFiles(); int cnt = fileList.length; System.out.println("count calculated"); // sned file count to server msgToServer.println(Integer.toString(cnt)); System.out.println("count sent to server"); // THIS LINE PRINTS } } catch(Exception ex) { ex.printStackTrace(); } } } } class UserThread extends Thread { String folderPath; String msg; BufferedReader msgFromServer,msgFromUser; PrintWriter msgToServer; InputStream fileFromServer; OutputStream fileToServer; public UserThread(String path,BufferedReader fromUser,BufferedReader fromServer,PrintWriter toServer,InputStream getFile,OutputStream sendFile) throws Exception { folderPath = path; msgFromUser = fromUser; msgFromServer = fromServer; msgToServer = toServer; fileFromServer = getFile; fileToServer = sendFile; } @Override public void run() { System.out.println("USer Thread Started"); while(true) { try { // input from user msg = msgFromUser.readLine(); if(msg.equals("get list")) { // send request to server msgToServer.println("get list"); msgToServer.println("fahim list"); } } catch(Exception ex) { ex.printStackTrace(); } } } } 

System.out.println("count sent to server");System.out.println("count sent to server"); 打印出来。 这意味着之前的消息发送行没有问题。

我知道服务器中的登录系统很愚蠢。 但这项工作“没问题”。 在所有客户端连接并登录到服务器之后,上面解释的所有内容都会发生。

我想我已经找到了问题。 我正在为客户端程序的ServerThread和UserThread使用相同的套接字。 因此,当ServerThread尝试响应服务器时,很可能该消息将通过同一套接字转发到正在侦听消息的服务器中的另一个不同的线程(认为消息来自UserThread)。