【问题标题】:Best way to handle (or) avoid too many "TCP_CLOSE_WAIT" state?处理(或)避免过多“TCP CLOSE_WAIT”状态的最佳方法?
【发布时间】:2018-07-03 03:27:26
【问题描述】:

我的服务器中有太多 tcp 关闭等待状态的原因是什么?我该如何解决这个问题?

这是我的 java 客户端调用以连接服务器的示例 sn-p

    HttpURLConnection urlConnection = (HttpURLConnection) (new URL(serverUrl).openConnection());
    urlConnection.setDoOutput(true);
    urlConnection.setDoInput(true);
    urlConnection.setRequestMethod("POST"); 
    urlConnection.setConnectTimeout(5000);
    urlConnection.setReadTimeout(60000);
    os = urlConnection.getOutputStream();

     //Write to output stream
    os.flush();
    os.close();

    urlConnection.connect();
    is = urlConnection.getInputStream();

    StringBuilder sb = new StringBuilder();
    br = new BufferedReader(new InputStreamReader(is));
    String eachLine = br.readLine();
    while (eachLine != null && "".equals(eachLine) == false) {
      sb.append(eachLine);
      eachLine = br.readLine();
    }
    br.close();
    is.close();
    return sb.toString();
    } catch (SocketTimeoutException se) {
             System.out.println("Socket time out exception ");
    } catch (Exception ioException) {
             System.out.println("IO Exception ");
    } finally {
       try {
        if (br != null) br.close();
       } catch (IOException ioe) {
        ioe.toString();
       }

      try {
        if (is != null) is.close();
      } catch (IOException ioe) {
        ioe.toString();
      }

      try {
       if (os != null) os.close(); 
      } catch (IOException ioe) {
       ioe.toString();
      }
    }

以下article 建议有关保持活动的时间,我可以将其与尝试将其与服务器连接的客户端代码相关联。

当异常发生时,客户端可以完整读取错误流,从而可以重用底层的tcp连接。

我什么时候可以得到太多的 tcp close_wait 状态,我该如何避免这种情况?

【问题讨论】:

  • “太多”是什么意思?这是连接关闭过程的正常部分。如果您在服务器上看到这些,则意味着客户端没有完成关闭过程就离开了。
  • @JimGarrison 不,它没有。这意味着服务器忽略客户端断开连接。本地 TCP 已收到 FIN 并正在等待本地应用程序关闭。而且一个太多了。在编写良好的服务器中不应该有任何端口处于 CLOSE_WAIT 状态,除非是非常短暂的。

标签: java sockets tcp httpurlconnection


【解决方案1】:

原因是您的服务器代码没有通过调用 close() 主动关闭客户端连接,从而使套接字处于“半关闭”状态。

要解决此问题,您的服务器应检测远程主机何时关闭连接并适当地关闭连接。如果您未能执行此操作,则连接将保持 CLOSE_WAIT 状态,直到进程本身终止并且操作系统关闭所有现有连接。

TCP 连接实际上由两个可以相互独立关闭的半连接组成。一端(如下图中的 A)可以在套接字上调用close(),表示它不会再发送任何数据,但另一端(如下图中的 B)可能只是 ACK 并继续向 A 发送数据。 /p>

(A calls close())
A -----FIN-----> B
FIN_WAIT_1       CLOSE_WAIT
A <----ACK------ B
FIN_WAIT_2

(B can send more data here, this is half-close state)

(B calls close())
A <----FIN------ B
TIME_WAIT        LAST_ACK
A -----ACK-----> B
|                CLOSED
2MSL Timer
|
CLOSED

【讨论】:

  • '最有可能'?还有什么其他原因?
  • @EJP 我真的不知道任何其他原因,只是措辞。将进行更准确的编辑。
  • 这不是知识的问题。我的观点是,根据定义,不可能有任何其他原因。这意味着一件事。
  • 明白。我知道这不可能是任何其他原因,所以我改写了我的答案。感谢您的澄清。
【解决方案2】:

我的服务器中有太多 tcp 关闭等待状态的原因是什么?我该如何解决这个问题?

您的服务器正在泄漏套接字。它无法检测到客户端断开连接,或者忽略它们,并且没有关闭套接字。

您引用的链接无关紧要。

【讨论】:

    猜你喜欢
    • 2016-11-12
    • 1970-01-01
    • 2012-02-08
    • 1970-01-01
    • 2021-09-13
    • 1970-01-01
    • 2023-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多