两分钟后插座时间虽然超过两分钟 [英] Socket time out after two minutes although set to more than two mintues

查看:88
本文介绍了两分钟后插座时间虽然超过两分钟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这篇文章之后,我遇到了同样的问题,我设法用简单的测试模型重现它。我希望你能帮助我。

following this post, I have the same problem and I managed to reproduce it with a simple test cast. I hope that you will be able to help me.

让我解释一下,我正在使用套接字发送消息。只要我将so_timeout设置为不到两分钟,一切都很好。但如果我将它设置为超过两分钟,套接字会在两分钟后超时。因此,如果我将so_timeout设置为10秒,套接字将在10秒后超时,但如果我将其设置为180秒,套接字将在120秒后超时。

Let me explain, I am sending messages using sockets. Everything is working great as long as I set the so_timeout to be less than two minutes. But if I set it to be more than two minutes the socket is timed out after two minutes. So, if I set the so_timeout to be 10 seconds the socket will be timed out after 10 seconds, but if I set it to be 180 seconds the socket will be timed out after 120 seconds.

以下是测试用例:

import java.io.*;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;

/**
 *
 */
public class TestSocket1 {

public static void main(String[] args) throws IOException {

    ServerSocket serverSocket = new ServerSocket();

    serverSocket.setReuseAddress(true);
    serverSocket.bind(new InetSocketAddress(1111), 0);
    serverSocket.setSoTimeout(1000);
    Socket socket = null;

    boolean send = true;

    while (send) {
        try {
            socket = serverSocket.accept();
            Thread.sleep(100);
            String messageReceived = readFromSocket(socket);

            System.out.println(messageReceived);

            if (send) {
                send = false;

                Thread.sleep(150000); // Causing 2.5 minutes delay
                // Sending message

                BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF8"));
                PrintWriter printWriter = new PrintWriter(wr, true);

                String output = "Hello Back";

                printWriter.println(output);
                printWriter.flush();
                socket.shutdownOutput();

            }

        }
        catch (SocketTimeoutException ie) {
        }
        catch (Exception e) {
        }
        finally {
            if (socket != null) {
                socket.close();
            }
        }
    }


}

protected static String readFromSocket(Socket socket) throws IOException {
    StringBuilder messageReceived = new StringBuilder();
    BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));

    String line = br.readLine();

    messageReceived.append(line);

    socket.shutdownInput();

    return messageReceived.toString();
}


}







import java.io.*;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;

/**
 *
 */
public class TestSocket2 {

public static void main(String[] args) throws IOException {

    Socket socket = new Socket();
    socket.setKeepAlive(true);
    socket.setReuseAddress(true);
    socket.setTcpNoDelay(true);
    socket.setSoTimeout(180000); // Should wait 3 minutes before throwing time out exception - Actually throwing after 2 minutes

    SocketAddress socketAddress = new InetSocketAddress(1111);

    socket.connect(socketAddress, 5000);

    // Sending message

    BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF8"));
    PrintWriter printWriter = new PrintWriter(wr, true);

    String output = "Hello There";

    printWriter.println(output);
    printWriter.flush();
    socket.shutdownOutput();

    String messageReceived = readFromSocket(socket);

    System.out.println(messageReceived);

}

protected static String readFromSocket(Socket socket) throws IOException {
    StringBuilder messageReceived = new StringBuilder();
    BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));

    String line = br.readLine();

    messageReceived.append(line);

    socket.shutdownInput();

    return messageReceived.toString();
}


}

你应该跑步首先是TestSocket1类,然后是TestSocket2。

You should run the TestSocket1 class first and then TestSocket2.

我很长时间都在努力解决这个问题,我们将不胜感激。谢谢。

I am struggling with this problem for a long time and any help will be appreciated. Thank you.


  • 编辑

所以我删除了依赖于SO_TimeOut并在这篇文章在阅读之前检查可用的输入流。但现在的问题是,在两分钟后,可用字节总是返回0,尽管输入被写入流。所以我仍然有同样的问题。

So I removed the dependency on SO_TimeOut and took @Nick suggestion in this post to check the available input stream before reading it. But now the problem is that after two minutes the available bytes always return 0 although the input was written to the stream. So I still have the same problem.

推荐答案

所以我想出了问题是什么

So I figured out what was the problem the

socket.shutdownInput();

导致套接字更改为FIN_WAIT状态,因此在关闭前等待2分钟( 2MSL

cause the socket to change to FIN_WAIT state thus wait 2 minutes before closing (2MSL)

这篇关于两分钟后插座时间虽然超过两分钟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆