Hi,
This is a behavior of the TCP socket in Java I dont' understand:.
Let say we have a simple client/server application running on TWO different
machines.
The client send bytes to the server.
The server recieved the bytes and wait for about X sec.
During this waiting time, we disconnect the server from the network (just by
unplugging the server network cable).
After the waiting time the server is aware of the network failure (a
SocketException is thrown : connection reset, because it is trying to send
the response)
But on the client side it is still stuck on a "rcv =
commandInput.readLine();" statement (see after for the complete code), it
will never be aware of the network failure !!! Even after one hour the
client is still waiting to read something on a closed socket. Is this the
normal behavior ?
In reality we are dealing with an application that use the FTP server to
server mode (we are controlling only the command socket, the data transfer
is made by the servers). We have to transfer huge files, thus we can not set
up a time out. If the last scenario occurs, some of our transfers are stuck
and it is not possible for us to detect the failure. The client will wait
for ever the response.
Does anybody have already deal with that ?
Below is the simple client and server I made in order to make my experiment.
The client just read the keyboard input and send it to the server; the
server just echo the request except if the request
is 'wait X', in this case it will wait for X sec before responding.
Thanks by advance,
Olivier MERIGON
CLIENT:
package com.iratensolutions.test.ftp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
/**
* A Client/Server application to test the network failure behavior with TCP.
* This the client part. It just sends the keyboard input to the server.
* @author Olivier MERIGON
*/
public class TestNetworkFailureClient {
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("usage: java
com.iratensolutions.test.ftp.TestNetworkFailureClient serverAdress");
}
Socket commandSocket = null;
BufferedReader commandInput;
BufferedReader keyboardInput;
PrintWriter commandOutput;
try {
commandSocket = new Socket(args[0], 666);
commandInput = new BufferedReader(new
InputStreamReader(commandSocket.getInputStream()));
keyboardInput = new BufferedReader(new InputStreamReader(System.in));
commandOutput = new PrintWriter(new
OutputStreamWriter(commandSocket.getOutputStream()));
} catch (Exception e) {
e.printStackTrace();
return;
}
System.out.println("CLIENT STARTED");
String snd;
String rcv = null;
try {
do {
System.out.print("KEYBOARD: ");
snd = keyboardInput.readLine();
if (snd != null) {
commandOutput.println(snd);
commandOutput.flush();
System.out.println("SND: " + snd);
rcv = commandInput.readLine();
System.out.println("RCV: " + rcv);
}
} while (rcv != null);
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
SERVER
package com.iratensolutions.test.ftp;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* A Client/Server application to test the network failure behavior with TCP.
* This the server part. The server can wait X second after responding to a
request.
* If a wait request is received, the server just answer the time waited
after
* the requested wait time, otherwise it respond immediatly the request
number.
* usage: wait intNbSec | any text
* @author Olivier MERIGON
*/
public class TestNetworkFailureServer {
public static void main(String args[]) {
ServerSocket echoServer = null;
String line;
DataInputStream is;
PrintStream os;
Socket clientSocket = null;
try {
echoServer = new ServerSocket(666);
System.out.println("SERVER STARTED");
} catch (IOException e) {
System.out.println(e);
}
while (true) {
try {
clientSocket = echoServer.accept();
System.out.println("Handling new client...");
is = new DataInputStream(clientSocket.getInputStream());
os = new PrintStream(clientSocket.getOutputStream());
int loopId = 0;
do {
line = is.readLine();
System.out.println("RCV: " + line);
//Handle "Wait" command
if (line.trim().startsWith("wait")) {
String[] tab = line.split("\\s");
boolean ok = false;
try {
int nbSec = Integer.parseInt(tab[1]);
System.out.println("...waiting for " + nbSec + " sec.");
try {
Thread.sleep(nbSec * 1000);
} catch (InterruptedException e1) {
}
String resp = "...end of wainting periode of " + nbSec + " sec.";
os.println(resp);
System.out.println("SND: " + resp);
ok = true;
} catch (Exception e) {
ok = false;
}
if (!ok) {
String resp = "usage: wait intNbSec | any text";
os.println(resp);
System.out.println("SND: " + resp);
}
//Handle "normal" action
} else {
os.println("# " + loopId);
System.out.println("SND: # " + loopId);
}
loopId++;
} while (line != null);
} catch (IOException e) {
System.out.println(e);
}
}
}
}