PHP cURL:CURLOPT_CONNECTTIMEOUT 与 CURLOPT_TIMEOUT

问题描述 投票:0回答:6

PHP 有这两个与超时相关的选项:

CURLOPT_CONNECTTIMEOUT
CURLOPT_TIMEOUT

PHP 网站上的描述有点模糊。有什么区别?

使用现实世界的示例:假设您通过 cURL 将 GET 变量发送到 URL 并且希望接收返回的 XML,则

CURLOPT_CONNECTTIMEOUT
与连接到服务器所需的最长时间有关,并且
 CURLOPT_TIMEOUT
发回 XML 所需的最长时间?

php curl
6个回答
56
投票

CURLOPT_CONNECTTIMEOUT 是允许连接到服务器的最长时间(以秒为单位)。 可以设置为 0 以禁用此限制,但在生产环境中这是不可取的。

CURLOPT_TIMEOUT 是限制单个 cURL 扩展函数调用执行的最长时间(以秒为单位)。 请注意,此设置的值应包括 CURLOPT_CONNECTTIMEOUT 的值。

换句话说, CURLOPT_CONNECTTIMEOUT 是 CURLOPT_TIMEOUT 表示的时间段,因此 CURLOPT_TIMEOUT 的值应大于 CURLOPT_CONNECTTIMEOUT 的值。

来自 CURLOPT_CONNECTTIMEOUT 和 CURLOPT_TIMEOUT 之间的区别


55
投票

CURLOPT_CONNECTTIMEOUT 不是CURLOPT_TIMEOUT代表的一段时间

如果 CURLOPT_CONNECTTIMEOUT 设置为 3 秒,CURLOPT_TIMEOUT 设置为 4 秒,则执行可能最多需要 7 秒。

我通过模拟缓慢的服务器连接(iptables drop)来测试这一点。


9
投票

CURLOPT_CONNECTTIMEOUT 是仅连接到服务器的时间。

CURLOPT_TIMEOUT 是整个连接时间加上交换数据的时间。

因此,CURLOPT_TIMEOUT 始终包含 CURLOPT_CONNECTTIMEOUT。

验证使用 CURLINFO_CONNECT_TIME 和 CURLINFO_TOTAL_TIME 是否非常容易。

  • curl_getinfo($ch, CURLINFO_CONNECT_TIME) 获取信息,curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $yourMaxConnTime) 设置要连接的最大值。

  • curl_getinfo($ch, CURLINFO_TOTAL_TIME) 获取信息,curl_setopt($ch, CURLOPT_TIMEOUT, $yourMaxTotTime) 设置整个操作的最大值。

当然,$yourMaxTotTime 必须始终高于 $yourMaxConnTime。 所有这些值均以秒为单位。


9
投票

接受的答案不正确。请参阅 timeouts - Everything CURL 文档以获取正确的文档。

连接时间基本上涵盖了建立http连接的两个方面:

  • DNS解析
  • tcp 连接建立之前的时间。

CURLOPT_TIMEOUT 或 CURLOPT_TIMEOUT_MS 选项根本不涵盖这段时间。这些涵盖了我们开始通过刚刚在连接阶段建立的 TCP 连接谈论 HTTP 之后发生的所有事情。

这种区别给很多人带来了问题,但它确实允许设置相对较短的连接超时,因为如果服务器完全不可用,为什么还要等待呢?然而,您仍然可以将请求超时设置得相当长,以防服务的预期响应时间难以预测。

一般来说,对于生产设置,CURLOPT_CONNECTION_TIMEOUT 应小于 5 秒,并且 CURLOPT_TIMEOUT 应尽可能低(不会导致您定期删除请求)。


5
投票

除了接受的答案

根据源代码连接设置:如果两者都设置,则使用最严格的设置。但仅限于连接阶段。

/* if a timeout is set, use the most restrictive one */

  if(data->set.timeout > 0)
    timeout_set |= 1;
  if(duringconnect && (data->set.connecttimeout > 0))
    timeout_set |= 2;

  switch(timeout_set) {
  //...
  case 3:
    if(data->set.timeout < data->set.connecttimeout)
      timeout_ms = data->set.timeout;
    else
      timeout_ms = data->set.connecttimeout;
    break;

源代码的单元测试


1
投票
致那些争论

CURLOPT_TIMEOUT

是否包含
CURLOPT_CONNECTTIMEOUT
的人;我会提醒您,libcurl 支持超过 23 种不同的操作系统,包括 DOS。

互联网连接极其复杂(代理、DNS 解析、IP 连接、IP 接受、SSH/SSL 握手、通过 HTTP 等特定协议进行实际数据传输),并且 libcurl 可能并不总是能够准确满足请求的超时。

经验法则是你应该设置

CURLOPT_TIMEOUT

 >= 
CURLOPT_CONNECTTIMEOUT
 因为这是手册所说的并且 libcurl 会尽力遵守。通常非常准确。

但在某些平台或边缘情况下,您很容易遇到实际超时为

CURLOPT_TIMEOUT

 + 
CURLOPT_CONNECTTIMEOUT
 的情况;或者哎呀,我什至遇到了所有超时都被忽略的情况,因为对于连接过程中的特定步骤,所涉及的操作系统/框架不要求超时值,并且不会将控制权返回给 libcurl;这超出了 libcurl 的控制范围。

© www.soinside.com 2019 - 2024. All rights reserved.