在第一个 SocketTimeoutException 之后接收 EOFException

发布于 2024-11-29 16:49:47 字数 5733 浏览 6 评论 0原文

这是一个简单的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

鹤仙姿 2024-12-06 16:49:47

您是否尝试增加超时值,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

仄言 2024-12-06 16:49:47

如果您收到 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文