Receive EOFException after the first SocketTimeoutException
This is a simple TCP Server (echo) and TCP Client in Java.
If I comment the following line, the program is working:
st.setSoTimeout(WAITING_FOR_INPUT);
But if I use this socket timeout method, then I will get first an InterruptedIOException (it's still good). But in the next iteration I will get an EOFException (this is the problem).
I don't understand, what's wrong? Please help!
CSimpleServer.java
import java.io.*;
import java.net.*;
public class CSimpleServer
{
public static final int WAITING_FOR_INPUT = 10; // 10 ms
public CServerThread st;
public class CServerThread extends Thread
{
ServerSocket ss;
Socket st;
ObjectInputStream in;
ObjectOutputStream out;
int sleeping_time;
int port;
CServerThread(int port, int sleeping_time)
{
st = null;
in = null;
out = null;
this.port = port;
this.sleeping_time = sleeping_time;
}
public void run()
{
try {
ss = new ServerSocket(port);
}
catch (IOException ioe) {
System.err.println("Create server failed: " + ioe.getMessage());
return;
}
try {
st = ss.accept();
st.setSoTimeout(WAITING_FOR_INPUT);
out = new ObjectOutputStream(st.getOutputStream());
out.flush();
in = new ObjectInputStream(st.getInputStream());
开发者_高级运维 }
catch (IOException ioe) {
System.err.println("Catch connection failed: " + ioe.getMessage());
return;
}
while (true) {
try {
int i_data = in.readInt();
if (i_data == 0) {
break;
}
System.out.println("Get: " + i_data);
out.writeInt(i_data);
out.flush();
out.reset();
sleep(sleeping_time);
}
catch (InterruptedIOException ire) {
System.out.println("Read data timeout."); // for debug
continue;
}
catch (EOFException eof) {
System.err.println("Reach end of stream: " + eof.getMessage());
break;
}
catch (IOException ioe) {
System.err.println("Read data failed: " + ioe.getMessage());
break;
}
catch (InterruptedException ire) {
System.err.println("Something interrupted this thread: " + ire.getMessage());
}
}
try {
in.close();
out.close();
st.close();
ss.close();
}
catch (IOException ioe) {
System.err.println("Close server failed: " + ioe.getMessage());
return;
}
}
}
CSimpleServer()
{
st = null;
}
public static void main(String[] args)
{
CSimpleServer prog = new CSimpleServer();
prog.st = prog.new CServerThread(3800, 1000);
prog.st.start();
}
}
CSimpleClient.java
import java.io.*;
import java.net.*;
public class CSimpleClient
{
public CClientThread ct;
public class CClientThread extends Thread
{
Socket st;
ObjectInputStream in;
ObjectOutputStream out;
int port;
CClientThread(int port)
{
st = null;
in = null;
out = null;
this.port = port;
}
public void run()
{
try {
st = new Socket(InetAddress.getLocalHost(), port);
out = new ObjectOutputStream(st.getOutputStream());
out.flush();
in = new ObjectInputStream(st.getInputStream());
}
catch (UnknownHostException uhe) {
System.err.println("Unknown server: " + uhe.getMessage());
return;
}
catch (IOException ioe) {
System.err.println("Connect to server failed: " + ioe.getMessage());
return;
}
BufferedReader ink = new BufferedReader(new InputStreamReader(System.in));
while (true) {
try {
String s = ink.readLine();
int i_data = Integer.valueOf(s);
out.writeInt(i_data);
out.flush();
out.reset();
if (i_data == 0) {
ink.close();
break;
}
i_data = in.readInt();
System.out.println("Echo: " + i_data);
}
catch (IOException ioe) {
System.err.println("Send/read data failed: " + ioe.getMessage());
break;
}
}
try {
in.close();
out.close();
st.close();
}
catch (IOException ioe) {
System.err.println("Close client failed: " + ioe.getMessage());
return;
}
}
}
CSimpleClient()
{
ct = null;
}
public static void main(String[] args)
{
CSimpleClient prog = new CSimpleClient();
prog.ct = prog.new CClientThread(3800);
prog.ct.start();
}
}
Did you try to increase the timeout value, 10 ms is quite a fast network, depending on the context...
BTW, I like to give constants units in their names, code is more readable.
Regards, Stéphane
If you got EOFException
it means the peer closed the connection, no two ways about that.
I agree with Snicolas. 10ms is an absurdly short timeout. Set it to at least 5 seconds.
You should also set the timeout after creating the ObjectInputStream
.
精彩评论