O
Olivier Merigon
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.i
utputStreamWriter;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:
javacom.iratensolutions.test.ftp.TestNetworkFailureClient
serverAdress");}Socket commandSocket = null;BufferedReader
commandInput;BufferedReader keyboardInput;PrintWriter commandOutput;try
{commandSocket = new Socket(args[0], 666);commandInput = new
BufferedReader(newInputStreamReader(commandSocket.getInputStream()));keyboar
dInput = new BufferedReader(new InputStreamReader(System.in));commandOutput
= new PrintWriter(newOutputStreamWriter(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 arequest.* If a wait
request is received, the server just answer the time waitedafter* the
requested wait time, otherwise it respond immediatly the requestnumber.*
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" commandif
(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);}}}}
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.i
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:
javacom.iratensolutions.test.ftp.TestNetworkFailureClient
serverAdress");}Socket commandSocket = null;BufferedReader
commandInput;BufferedReader keyboardInput;PrintWriter commandOutput;try
{commandSocket = new Socket(args[0], 666);commandInput = new
BufferedReader(newInputStreamReader(commandSocket.getInputStream()));keyboar
dInput = new BufferedReader(new InputStreamReader(System.in));commandOutput
= new PrintWriter(newOutputStreamWriter(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 arequest.* If a wait
request is received, the server just answer the time waitedafter* the
requested wait time, otherwise it respond immediatly the requestnumber.*
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" commandif
(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);}}}}