简体   繁体   中英

PHP cURL: CURLOPT_CONNECTTIMEOUT vs CURLOPT_TIMEOUT

PHP has these two options related to timeout: CURLOPT_CONNECTTIMEOUT and CURLOPT_TIMEOUT .

The descriptions on the PHP site are a bit vague. 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?

CURLOPT_CONNECTTIMEOUT is the maximum amount of time in seconds that is allowed to make the connection to the server. It can be set to 0 to disable this limit, but this is inadvisable in a production environment.

CURLOPT_TIMEOUT is a maximum amount of time in seconds to which the execution of individual cURL extension function calls will be limited. Note that the value for this setting should include the value for 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.

From Difference between CURLOPT_CONNECTTIMEOUT and CURLOPT_TIMEOUT

CURLOPT_CONNECTTIMEOUT is not a segment of the time represented by CURLOPT_TIMEOUT

If CURLOPT_CONNECTTIMEOUT is set to 3 seconds and CURLOPT_TIMEOUT to 4 seconds, execution may take up to 7 seconds.

I tested this by simulating slow server connecting (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.

Basically the connection time covers two aspects of establishing an http connection:

  • DNS resolution
  • Time until the tcp connection is established.

This period of time is NOT AT ALL covered by the CURLOPT_TIMEOUT or CURLOPT_TIMEOUT_MS options. These cover everything that happens after we start talking HTTP over the TCP connection that was just established in the connection phase.

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_CONNECTTIMEOUT is the the time to connect to the server only.

CURLOPT_TIMEOUT is the whole time to connect plus the time to exchange data.

So, CURLOPT_TIMEOUT includes CURLOPT_CONNECTTIMEOUT always.

To verify that it's very easy using CURLINFO_CONNECT_TIME and 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_TOTAL_TIME) gets the info and curl_setopt($ch, CURLOPT_TIMEOUT, $yourMaxTotTime) sets the max value of the whole operation.

Of course, $yourMaxTotTime must be higher that $yourMaxConnTime always. All these values are in seconds.

To those arguing whether CURLOPT_TIMEOUT includes CURLOPT_CONNECTTIMEOUT or not; I'll remind you that libcurl supports more than 23 different OSes, including 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.

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. 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 ; 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; and that's something beyond libcurl's control.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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