简体   繁体   English

PHP cURL:CURLOPT_CONNECTTIMEOUT 与 CURLOPT_TIMEOUT

[英]PHP cURL: CURLOPT_CONNECTTIMEOUT vs CURLOPT_TIMEOUT

PHP has these two options related to timeout: CURLOPT_CONNECTTIMEOUT and CURLOPT_TIMEOUT . PHP 有这两个与超时相关的选项: CURLOPT_CONNECTTIMEOUTCURLOPT_TIMEOUT

The descriptions on the PHP site are a bit vague. PHP网站上的描述有点模糊。 What's the difference?有什么不同?

To use a real world example: say you're sending GET vars to a URL via cURL and you want to receive a XML back, would CURLOPT_CONNECTTIMEOUT relate to the maximum amount of time it can take to connect to the server and CURLOPT_TIMEOUT the maximum amount of time it can take to send the XML back?使用一个真实世界的例子:假设你通过 cURL 发送 GET vars 到 URL 并且你想收到一个 XML 回来, CURLOPT_CONNECTTIMEOUT与连接到服务器所需的最长时间有关,而CURLOPT_TIMEOUT与最大数量有关发送 XML 需要多少时间?

CURLOPT_CONNECTTIMEOUT is the maximum amount of time in seconds that is allowed to make the connection to the server. CURLOPT_CONNECTTIMEOUT是与服务器建立连接所允许的最长时间(以秒为单位)。 It can be set to 0 to disable this limit, but this is inadvisable in a production environment. 可以将其设置为0以禁用此限制,但这在生产环境中是不可取的。

CURLOPT_TIMEOUT is a maximum amount of time in seconds to which the execution of individual cURL extension function calls will be limited. CURLOPT_TIMEOUT是限制执行单​​个cURL扩展函数调用的最长时间(以秒为单位)。 Note that the value for this setting should include the value for CURLOPT_CONNECTTIMEOUT. 请注意,此设置的值应包含CURLOPT_CONNECTTIMEOUT的值。

In other words, CURLOPT_CONNECTTIMEOUT is a segment of the time represented by CURLOPT_TIMEOUT, so the value of the CURLOPT_TIMEOUT should be greater than the value of the CURLOPT_CONNECTTIMEOUT. 换句话说,CURLOPT_CONNECTTIMEOUT是CURLOPT_TIMEOUT表示的时间段,因此CURLOPT_TIMEOUT的值应该大于CURLOPT_CONNECTTIMEOUT的值。

From Difference between CURLOPT_CONNECTTIMEOUT and CURLOPT_TIMEOUT 来自CURLOPT_CONNECTTIMEOUT和CURLOPT_TIMEOUT之间的差异

CURLOPT_CONNECTTIMEOUT is not a segment of the time represented by CURLOPT_TIMEOUT CURLOPT_CONNECTTIMEOUT 不是 CURLOPT_TIMEOUT表示的时间段

If CURLOPT_CONNECTTIMEOUT is set to 3 seconds and CURLOPT_TIMEOUT to 4 seconds, execution may take up to 7 seconds. 如果CURLOPT_CONNECTTIMEOUT设置为3秒而CURLOPT_TIMEOUT设置为4秒,则执行最多可能需要7秒。

I tested this by simulating slow server connecting (iptables drop). 我通过模拟慢速服务器连接(iptables drop)测试了这个。

In addition to the accepted answer . 除了接受的答案

According to the source code the settings are connected: if both are set, the most restrictive is used. 根据源代码 ,设置是连接的:如果两者都设置,则使用最严格的限制。 But only in the connection stage. 但只是在连接阶段。

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

Unit tests for the source 源的单元测试

The accepted answer is incorrect. 接受的答案是不正确的。 See the Everything CURL documentation for proper documentation. 有关正确的文档,请参阅Everything CURL文档。

Basically the connection time covers two aspects of establishing an http connection: 基本上连接时间包括建立http连接的两个方面:

  • DNS resolution DNS解析
  • Time until the tcp connection is established. 建立tcp连接的时间。

This period of time is NOT AT ALL covered by the CURLOPT_TIMEOUT or CURLOPT_TIMEOUT_MS options. CURLOPT_TIMEOUT或CURLOPT_TIMEOUT_MS选项并未涵盖这段时间。 These cover everything that happens after we start talking HTTP over the TCP connection that was just established in the connection phase. 这些内容涵盖了我们开始通过刚刚在连接阶段建立的TCP连接谈论HTTP之后发生的所有事情。

This distinction causes problems for lots of people, but it does allow one to set a relatively short connection timeout, because if the server is completely unavailable why wait for it? 这种区别会给很多人带来问题,但它确实允许设置相对较短的连接超时,因为如果服务器完全不可用,为什么要等待呢? Yet you can still have your request timeout be reasonably long, in case expected response times for the service are hard to predict. 但是,如果服务的预期响应时间难以预测,您仍然可以将请求超时合理地延长。

In general, for production setups, CURLOPT_CONNECTION_TIMEOUT should be less than 5 seconds and CURLOPT_TIMEOUT should be as low as possible (without causing you to regularly drop requests). 通常,对于生产设置,CURLOPT_CONNECTION_TIMEOUT应小于5秒,CURLOPT_TIMEOUT应尽可能低(不会导致您定期删除请求)。

CURLOPT_CONNECTTIMEOUT is the the time to connect to the server only. CURLOPT_CONNECTTIMEOUT是仅连接到服务器的时间。

CURLOPT_TIMEOUT is the whole time to connect plus the time to exchange data. CURLOPT_TIMEOUT是连接的全部时间加上交换数据的时间。

So, CURLOPT_TIMEOUT includes CURLOPT_CONNECTTIMEOUT always. 因此,CURLOPT_TIMEOUT总是包含CURLOPT_CONNECTTIMEOUT。

To verify that it's very easy using CURLINFO_CONNECT_TIME and CURLINFO_TOTAL_TIME. 要使用CURLINFO_CONNECT_TIME和CURLINFO_TOTAL_TIME验证它是否非常简单。

  • curl_getinfo($ch, CURLINFO_CONNECT_TIME) gets the info and curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $yourMaxConnTime) sets the max value to connect. curl_getinfo($ ch,CURLINFO_CONNECT_TIME)获取信息,curl_setopt($ ch,CURLOPT_CONNECTTIMEOUT,$ yourMaxConnTime)设置要连接的最大值。

  • curl_getinfo($ch, CURLINFO_TOTAL_TIME) gets the info and curl_setopt($ch, CURLOPT_TIMEOUT, $yourMaxTotTime) sets the max value of the whole operation. curl_getinfo($ ch,CURLINFO_TOTAL_TIME)获取信息,curl_setopt($ ch,CURLOPT_TIMEOUT,$ yourMaxTotTime)设置整个操作的最大值。

Of course, $yourMaxTotTime must be higher that $yourMaxConnTime always. 当然,$ yourMaxTotTime必须始终高于$ yourMaxConnTime。 All these values are in seconds. 所有这些值都是秒。

To those arguing whether CURLOPT_TIMEOUT includes CURLOPT_CONNECTTIMEOUT or not;对于那些争论CURLOPT_TIMEOUT是否包含CURLOPT_CONNECTTIMEOUT的人; I'll remind you that libcurl supports more than 23 different OSes, including DOS.我会提醒您,libcurl 支持超过 23 种不同的操作系统,包括 DOS。

Inte.net connections are incredibly complex (proxies, DNS resolution, IP connect, IP accept, SSH/SSL handshake, actual data transmission over a specific protocol like HTTP) and it may not always be possible for libcurl to honour exactly the timeouts requested. Inte.net 连接非常复杂(代理、DNS 分辨率、IP 连接、IP 接受、SSH/SSL 握手、通过特定协议(如 HTTP)的实际数据传输),libcurl 可能并不总是能够准确地遵守请求的超时。

The rule of thumbs is that you should set CURLOPT_TIMEOUT >= CURLOPT_CONNECTTIMEOUT because that's what the manual says and libcurl will try to honour.经验法则是您应该设置CURLOPT_TIMEOUT >= CURLOPT_CONNECTTIMEOUT因为这是手册所说的并且 libcurl 会尽力遵守。 Often with extreme accuracy.通常具有极高的准确性。

But on some platforms or edge cases you can easily run into situations where the actual timeout was CURLOPT_TIMEOUT + CURLOPT_CONNECTTIMEOUT ;但在某些平台或边缘情况下,您很容易遇到实际超时为CURLOPT_TIMEOUT + CURLOPT_CONNECTTIMEOUT的情况; or heck, I even ran into situations where all timeouts are ignored because for a specific step in the connection process the OS/framework involved doesn't ask for a timeout value and won't return control to libcurl;或者哎呀,我什至遇到了所有超时都被忽略的情况,因为对于连接过程中的特定步骤,涉及的操作系统/框架不要求超时值并且不会将控制权返回给 libcurl; and that's something beyond libcurl's control.这超出了 libcurl 的控制范围。

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

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