繁体   English   中英

PHP cURL:CURLOPT_CONNECTTIMEOUT 与 CURLOPT_TIMEOUT

[英]PHP cURL: CURLOPT_CONNECTTIMEOUT vs CURLOPT_TIMEOUT

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

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

使用一个真实世界的例子:假设你通过 cURL 发送 GET vars 到 URL 并且你想收到一个 XML 回来, CURLOPT_CONNECTTIMEOUT与连接到服务器所需的最长时间有关,而CURLOPT_TIMEOUT与最大数量有关发送 XML 需要多少时间?

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

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

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

来自CURLOPT_CONNECTTIMEOUT和CURLOPT_TIMEOUT之间的差异

CURLOPT_CONNECTTIMEOUT 不是 CURLOPT_TIMEOUT表示的时间段

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

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

除了接受的答案

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

/* 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;

源的单元测试

接受的答案是不正确的。 有关正确的文档,请参阅Everything CURL文档。

基本上连接时间包括建立http连接的两个方面:

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

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

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

通常,对于生产设置,CURLOPT_CONNECTION_TIMEOUT应小于5秒,CURLOPT_TIMEOUT应尽可能低(不会导致您定期删除请求)。

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。 所有这些值都是秒。

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

Inte.net 连接非常复杂(代理、DNS 分辨率、IP 连接、IP 接受、SSH/SSL 握手、通过特定协议(如 HTTP)的实际数据传输),libcurl 可能并不总是能够准确地遵守请求的超时。

经验法则是您应该设置CURLOPT_TIMEOUT >= CURLOPT_CONNECTTIMEOUT因为这是手册所说的并且 libcurl 会尽力遵守。 通常具有极高的准确性。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM