I'm working on a Java project where a client sends some files to the server using sockets, on which he should perform some operations and send the results back.
This process was working perfectly fine on my PC, but when I ran the client on my friend's PC (after we connected to the same network, and changed the IP in the client.java from localhost to the server's IP), the connection timed out.
The client successfully pings the server, but the command telnet <server_ip> <port>
shows that the connection failed. We tried everything, disabled firewall, allowed inbound and outbound connections from that port, disabled antivirus, made sure the server is running on that port, and we still got connection failed from the client side.
Any help or suggestion is greatly appreciated.
server.java
package server;
import common.ServerInterface;
import common.Task;
import common.Result;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.RemoteException;
import java.rmi.Naming;
import java.ServerSocket;
import java.Socket;
import java.io.*;
import java.util.Stack;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class Server extends UnicastRemoteObject implements ServerInterface {
private static final int PORT = 12345; // Listening Port
protected Server() throws RemoteException {
super();
}
private Stack<Task> taskStack = new Stack<>(); // Tasks
private Map<String, Result> results = new HashMap<>(); // stores result as task ID
@Override
public synchronized Task getTask() throws RemoteException {
if (!taskStack.isEmpty()) {
return taskStack.pop(); // Retuns task if available
}
return null; // no task available
}
@Override
public synchronized void returnResult(Result result, String taskId) throws RemoteException {
// stores the result
results.put(taskId, result);
System.out.println("Results were received from Worker through RMI for the task " + taskId + ": " + result);
}
public void startSocketServer() {
new Thread(() -> {
try (ServerSocket serverSocket = new ServerSocket(PORT)) {
System.out.println("Server is waiting for a connection on port " + PORT);
while (true) {
Socket clientSocket = serverSocket.accept();
System.out.println("Client connected : " + clientSocket.getInetAddress());
// Gérer la connexion client
new Thread(() -> handleClient(clientSocket)).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
private void handleClient(Socket clientSocket) {
try (InputStream is = clientSocket.getInputStream();
DataInputStream dis = new DataInputStream(is);
OutputStream os = clientSocket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os)) {
int fileCount = dis.readInt(); // read the number
String taskId = UUID.randomUUID().toString(); // generate ID for task
Task task = new Task(taskId); // create a new task
int textFileCount = 0;
for (int i = 0; i < fileCount; i++) {
String fileName = dis.readUTF(); // read file name
long fileSize = dis.readLong(); // read file size
byte[] fileContent = new byte[(int) fileSize];
dis.readFully(fileContent); // read all files on memory
if (fileName.endsWith(".txt")) {
String fileContentStr = new String(fileContent); // convert matrices to string
if (textFileCount == 0) {
task.setDataFile1Content(fileContentStr);
} else if (textFileCount == 1) {
task.setDataFile2Content(fileContentStr);
}
textFileCount++;
} else if (fileName.endsWith(".jar")) {
task.setOperationFileContent(fileContent); // stores in binary
}
}
taskStack.push(task); // Add task
System.out.println("Tak added : " + task);
// wait for result
while (!results.containsKey(taskId)) {
Thread.sleep(1000);
}
// send result back to the client
Result result = results.get(taskId);
dos.writeUTF(result.getValue());
System.out.println("Result sent to client : " + result);
clientSocket.close();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
Server server = new Server();
java.rmi.registry.LocateRegistry.createRegistry(1099);
Naming.rebind("Server", server);
System.out.println("Server RMI is ready");
// run server
server.startSocketServer();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Client.java
import java.io.*;
import java.Socket;
public class Client {
public void sendTask(String serverAddress, String[] filePaths) {
try (Socket socket = new Socket(serverAddress, 12345);
OutputStream os = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
InputStream is = socket.getInputStream();
DataInputStream dis = new DataInputStream(is)) {
// Send number of files
dos.writeInt(filePaths.length);
for (String filePath : filePaths) {
File file = new File(filePath);
if (!file.exists()) {
System.err.println("Error : File " + filePath + " does not exist !");
return;
}
// send file name
dos.writeUTF(file.getName());
// send file size
dos.writeLong(file.length());
// send file content
try (FileInputStream fis = new FileInputStream(file)) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
dos.write(buffer, 0, bytesRead);
}
}
}
System.out.println("Task was sent to server");
// receive final result
String result = dis.readUTF();
System.out.println("Results were received from the server : " + result);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Client client = new Client();
String[] files = {
"resources/data/A.txt",
"resources/data/B.txt",
"resources/operations/operation.jar"
};
client.sendTask("192.168.43.19", files);
}
}
I tried running the server on my PC, then I ran the client on another PC. I expected the files content to be sent, but the connection timed out. I tried disabling firewalls and adding rules to allow traffic for that port, still not resolved. I'm sure my code works, because it works perfectly on my PC using localhost.
I'm working on a Java project where a client sends some files to the server using sockets, on which he should perform some operations and send the results back.
This process was working perfectly fine on my PC, but when I ran the client on my friend's PC (after we connected to the same network, and changed the IP in the client.java from localhost to the server's IP), the connection timed out.
The client successfully pings the server, but the command telnet <server_ip> <port>
shows that the connection failed. We tried everything, disabled firewall, allowed inbound and outbound connections from that port, disabled antivirus, made sure the server is running on that port, and we still got connection failed from the client side.
Any help or suggestion is greatly appreciated.
server.java
package server;
import common.ServerInterface;
import common.Task;
import common.Result;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.RemoteException;
import java.rmi.Naming;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.*;
import java.util.Stack;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class Server extends UnicastRemoteObject implements ServerInterface {
private static final int PORT = 12345; // Listening Port
protected Server() throws RemoteException {
super();
}
private Stack<Task> taskStack = new Stack<>(); // Tasks
private Map<String, Result> results = new HashMap<>(); // stores result as task ID
@Override
public synchronized Task getTask() throws RemoteException {
if (!taskStack.isEmpty()) {
return taskStack.pop(); // Retuns task if available
}
return null; // no task available
}
@Override
public synchronized void returnResult(Result result, String taskId) throws RemoteException {
// stores the result
results.put(taskId, result);
System.out.println("Results were received from Worker through RMI for the task " + taskId + ": " + result);
}
public void startSocketServer() {
new Thread(() -> {
try (ServerSocket serverSocket = new ServerSocket(PORT)) {
System.out.println("Server is waiting for a connection on port " + PORT);
while (true) {
Socket clientSocket = serverSocket.accept();
System.out.println("Client connected : " + clientSocket.getInetAddress());
// Gérer la connexion client
new Thread(() -> handleClient(clientSocket)).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
private void handleClient(Socket clientSocket) {
try (InputStream is = clientSocket.getInputStream();
DataInputStream dis = new DataInputStream(is);
OutputStream os = clientSocket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os)) {
int fileCount = dis.readInt(); // read the number
String taskId = UUID.randomUUID().toString(); // generate ID for task
Task task = new Task(taskId); // create a new task
int textFileCount = 0;
for (int i = 0; i < fileCount; i++) {
String fileName = dis.readUTF(); // read file name
long fileSize = dis.readLong(); // read file size
byte[] fileContent = new byte[(int) fileSize];
dis.readFully(fileContent); // read all files on memory
if (fileName.endsWith(".txt")) {
String fileContentStr = new String(fileContent); // convert matrices to string
if (textFileCount == 0) {
task.setDataFile1Content(fileContentStr);
} else if (textFileCount == 1) {
task.setDataFile2Content(fileContentStr);
}
textFileCount++;
} else if (fileName.endsWith(".jar")) {
task.setOperationFileContent(fileContent); // stores in binary
}
}
taskStack.push(task); // Add task
System.out.println("Tak added : " + task);
// wait for result
while (!results.containsKey(taskId)) {
Thread.sleep(1000);
}
// send result back to the client
Result result = results.get(taskId);
dos.writeUTF(result.getValue());
System.out.println("Result sent to client : " + result);
clientSocket.close();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
Server server = new Server();
java.rmi.registry.LocateRegistry.createRegistry(1099);
Naming.rebind("Server", server);
System.out.println("Server RMI is ready");
// run server
server.startSocketServer();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Client.java
import java.io.*;
import java.net.Socket;
public class Client {
public void sendTask(String serverAddress, String[] filePaths) {
try (Socket socket = new Socket(serverAddress, 12345);
OutputStream os = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
InputStream is = socket.getInputStream();
DataInputStream dis = new DataInputStream(is)) {
// Send number of files
dos.writeInt(filePaths.length);
for (String filePath : filePaths) {
File file = new File(filePath);
if (!file.exists()) {
System.err.println("Error : File " + filePath + " does not exist !");
return;
}
// send file name
dos.writeUTF(file.getName());
// send file size
dos.writeLong(file.length());
// send file content
try (FileInputStream fis = new FileInputStream(file)) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
dos.write(buffer, 0, bytesRead);
}
}
}
System.out.println("Task was sent to server");
// receive final result
String result = dis.readUTF();
System.out.println("Results were received from the server : " + result);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Client client = new Client();
String[] files = {
"resources/data/A.txt",
"resources/data/B.txt",
"resources/operations/operation.jar"
};
client.sendTask("192.168.43.19", files);
}
}
I tried running the server on my PC, then I ran the client on another PC. I expected the files content to be sent, but the connection timed out. I tried disabling firewalls and adding rules to allow traffic for that port, still not resolved. I'm sure my code works, because it works perfectly on my PC using localhost.
Share Improve this question edited yesterday Mark Rotteveel 109k226 gold badges155 silver badges219 bronze badges asked yesterday ms maamms maam 1 New contributor ms maam is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct. 12 | Show 7 more comments1 Answer
Reset to default 0It's time you equip yourself with diag tools for linux (windows):
tcpdump (wireshark), to see packets flying. On each end, in case half of them pass. You'd also see if it is a tcp RST or FIN or nothing. Here, it looks like the initial SYN doesn't get any response, but the server might have seen the SYN and tries to respond but packet can't get through.
netstat (resource monitor or tcpview), to see the bind address of the server port. If it is bound only to localhost (127.0.0.1 or ::1 in ipv6), it would not accept a SYN on your 192.168.... interface.
(Also, you could simplify your example by removing the distracting rmi stuff).
As for firewalls, you'd be surprised how many broad rules could catch your process. You don't say if it is linux or windows, but on windows there is always the possibility that the rules are overlapping. I use malwarebytes WFC (windows firewall control) to view the connection failed log and which rule caused it. It can also find duplicates rules. Pay attention to which java.exe or javaw.exe might be running, using detailed process lists. I'm not familiar with linux firewalls.
In the end, there is also the possibility for a switch or router to interfere with this. You may need ultimately access to those (or someone who does).
telnet
is being used as a general networking tool, not specifically for the telnet protocol. To the OP: you really need to consider firewall rules on the router first. In fact you should really start from that point conceptually – g00se Commented yesterday