在这篇文章之后,我遇到了同样的问题,我设法用一个简单的测试版重现它.我希望你能帮助我.
让我解释一下,我正在使用套接字发送消息.只要我将so_timeout设置为不到两分钟,一切都很好.但如果我将它设置为超过两分钟,套接字会在两分钟后超时.因此,如果我将so_timeout设置为10秒,则套接字将在10秒后超时,但如果我将其设置为180秒,套接字将在120秒后超时.
这是一个测试用例:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
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();
}
}
Run Code Online (Sandbox Code Playgroud)
您应首先运行TestSocket1类,然后运行TestSocket2.
我很长时间都在努力解决这个问题,任何帮助都将受到赞赏.谢谢.
所以我删除了对SO_TimeOut的依赖,并在这篇文章中采用@Nick建议来检查可用的输入流,然后再读取它.但现在的问题是,在两分钟后,可用字节总是返回0,尽管输入被写入流.所以我仍然有同样的问题.
所以我明白了问题是什么
socket.shutdownInput();
Run Code Online (Sandbox Code Playgroud)
导致套接字更改为 FIN_WAIT 状态,因此在关闭前等待 2 分钟(2MSL)