在第一个 SocketTimeoutException 之后接收 EOFException
这是一个简单的 Java 中的 TCP 服务器(echo)和 TCP 客户端。
如果我注释以下行,则程序正在运行:
st.setSoTimeout(WAITING_FOR_INPUT);
但如果我使用此套接字超时方法,那么我将首先得到 InterruptedIOException (它仍然很好)。但在下一次迭代中我将得到一个 EOFException (这就是问题所在)。
我不明白,有什么问题吗?请帮忙!
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();
}
}
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();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您是否尝试增加超时值,10 毫秒是一个相当快的网络,具体取决于上下文...
顺便说一句,我喜欢在名称中给出常量单位,代码更具可读性。
问候,
史蒂芬
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
如果您收到 EOFException ,则意味着对等方关闭了连接,没有两种方法可以解决此问题。
我同意斯尼古拉斯的观点。 10ms 是一个短得离谱的超时。将其设置为至少 5 秒。
您还应该在创建
ObjectInputStream
之后设置超时。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
.