PHP cURL:CURLOPT_CONNECTTIMEOUT与CURLOPT_TIMEOUT

tex*_*ate 33 php curl

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

PHP站点上的描述有点模糊.有什么不同?

要使用真实世界的示例:假设您通过cURL将GET变量发送到URL并且您希望接收XML,则CURLOPT_CONNECTTIMEOUT与连接到服务器CURLOPT_TIMEOUT所花费的最长时间和最长时间有关可以将XML发回去吗?

Pri*_*ank 42

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

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

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

来自CURLOPT_CONNECTTIMEOUT和CURLOPT_TIMEOUT之间的差异

  • 我想说,这是不是真的正确.[这里](https://curl.haxx.se/libcurl/c/CURLOPT_TIMEOUT.html)它说,那`CURLOPT_TIMEOUT`定义"在您允许的libcurl传输操作采取秒*的最长时间.*" .这是一个有点暧昧.我的经验似乎证实米洛什答案如下:`CURLOPT_CONNECTTIMEOUT`真的只是为*连接阶段*和`CURLOPT_TIMEOUT`对于*传输阶段*.两者都定义了`curl_exec()`的完全超时. (10认同)
  • -1,所使用的来源是不正确的非权威博客,如其自身的注释和此处的其他答案所示。 (2认同)
  • 我扫描了 CURL 源代码以确定,它似乎证实了这个答案。如果只设置了 CURLOPT_CONNECTTIMEOUT,那么只有连接阶段会受到它的影响。如果只设置了 CURLOPT_TIMEOUT,则它适用于整个 curl 操作,包括连接。但是,如果两者都设置,则连接阶段使用两个超时中较短的一个。参见 `curl/lib/connect.c` 中的函数 `Curl_timeleft()`。 (2认同)

小智 35

CURLOPT_CONNECTTIMEOUT 不是 CURLOPT_TIMEOUT表示的时间段

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

我通过模拟慢速服务器连接(iptables drop)测试了这个.

  • 你看过这个[评论](http://www.altafweb.com/2012/12/difference-between-curloptconnecttimeou.html?showComment=1458056670978#c2865373137896441937)? (2认同)
  • 根据我在源代码中读到的内容,这是不正确的,但如果你通过实验验证它,那就表明不同版本中有不同的实现......然而,GitHub 上的版本已经 12 年没有改变这个功能了。 (2认同)

小智 9

接受的答案是不正确的。请参阅Everything CURL文档以获取正确的文档。
.. 基本上连接时间涵盖了建立http连接的两个方面:

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

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

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

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


Joh*_*ohn 8

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。所有这些值均以秒为单位。


小智 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;
Run Code Online (Sandbox Code Playgroud)

源的单元测试