Reputation: 47
I am going for the simplest explanation. My Java TCP project has a server and three clients.
The server has a ClientThread. The clients each has a ServerThread and a UserThread.
The workflow is:
1. The UserThread of a client (say, client_0) gets user input and then sends a message to the server.
2. The ClientThread of the server captures the message from client_0 and sends another message to the ServerThread of a different client (say, client_1).
3. The ServerThread of client_1 then sends back another message to the ClientThread running in the server;
The message of step 3 is not reaching the server.
There are total 3 clients, say client_0, client_1 and client_2.
The original idea is that if client_0 requests the server then the server communicates with client_1 and client_2. That's why the line if(i==cid) continue;
in the for loop in the server. But, if i comment out this line, the server communicates with the client_0 (which is unnecessary semantically) and the messaging problem doesn't happen. After that the server communicates with client_1 and the problem appears again.
The server can receive message from the ServerThread of the client (client_0) that sent the original request (msgToServer.println("get list");
) from it's UserThread to initiate the whole process. But Server cannot get message from any other client's ServerThread even though it can send message to others and all the client programs are identical and all the ServerThreads and UserThreads should work the same eway. How is it even possible?
Server:
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();
}
}
}
}
The line System.out.println("file count caught!!!");
is never called.
Client:
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();
}
}
}
}
The line System.out.println("count sent to server");
is printed. That means the message sending line before that has executed with no problem.
I know the login system in the server is stupid. But it is 'ok' for this work. Everything explained above happens after all the clients have connected and logged in to the server.
Upvotes: 1
Views: 206
Reputation: 47
I think I have found the problem. I was using the same socket for a client program's ServerThread and UserThread. So while the ServerThread is trying to response to the server, most probably the message is going to another different thread in the server that is listening for message (thinking the message comes from UserThread) through the same socket.
Upvotes: 0