libcurl:连接保持活动如何工作?

cya*_*lin 3 c http libcurl

如何保持与 libcurl 的连接?

我想要的用法如下。Keep-Alive我想连接到支持但在 90 秒不活动后关闭连接的服务器。当某些事件(在此连接之外)发生时,我想POST偶尔执行一次,并且我想保持连接处于活动状态以减少延迟。可能会发生超过 90 秒没有事件发生的情况,所以我想要一种方法来告诉服务器我没有空闲。

示例页面非常好,但我没有看到涉及Keep-Alive: https: //curl.haxx.se/libcurl/c/example.html

我确实找到了CURLOPT_TCP_KEEPINTVL: https: //curl.haxx.se/libcurl/c/CURLOPT_TCP_KEEPINTVL.html,但我不清楚它应该如何工作。在该示例中,我们看到代码:

CURL *curl = curl_easy_init();
if(curl) {
  curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");

  /* enable TCP keep-alive for this transfer */
  curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);

  /* set keep-alive idle time to 120 seconds */
  curl_easy_setopt(curl, CURLOPT_TCP_KEEPIDLE, 120L);

  /* interval time between keep-alive probes: 60 seconds */
  curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, 60L);

  curl_easy_perform(curl);
}
Run Code Online (Sandbox Code Playgroud)

描述如下:

过了很长。设置操作系统在发送保活探测之​​间等待的时间间隔(以秒为单位)。并非所有操作系统都支持此选项。(7.25.0 中添加)

两个问题:

A) 在操作上,我该如何使用它?从描述来看,只要我保持curl在范围内,连接就会保持打开状态。它是否正确?然后我应该继续做吗

curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postthis);
res = curl_easy_perform(curl);
Run Code Online (Sandbox Code Playgroud)

每当我想要POST更多数据时,它将在同一连接中发送,或者还有更多数据吗?

B) 这些保活探针是什么?我在哪里可以阅读有关它们的更多信息?这是操作系统在我背后做的事情吗?我是否应该将此视为:从我的应用程序的角度来看,连接神奇地存在,我不应该担心它?


是的,我的意思是 HTTP Keep-Alive,抱歉含糊不清。

从昨天开始,我发现 Daniel Stenberg 本人在这里回答了类似的问题: https: //stackoverflow.com/a/14148171/12874900

这回答了我的问题的 A) 部分。但它没有回答问题B)。我还需要知道:如果连接确实因某种原因而中断,我该如何检测它?或者 libcurl 是否负责重新连接?

有人可以随意将其编辑到我的原始帖子中。

Dan*_*erg 9

HTTP 持久连接

正如多次说过的:libcurl 默认情况下会进行持久 HTTP 连接。您只需要重复使用卷曲手柄即可使其发挥作用,并且如果您不想要它们,则必须主动要求不要将它们持久化。使用哪种 HTTP 方法并不重要。GET、POST、HEAD 等都维持连接 - 除非发生异常情况。

然而,现代 libcurl 版本只会重用CURLOPT_MAXAGE_CONN秒(默认为 118)的连接 - 因为随着时间的推移,成功重用的机会会很快减少。

有时您会看到客户端使用Keep-Alive:标头,但这是 HTTP/1.0 时代遗留下来的,在当今时代几乎毫无意义。

如果如本问题所述,连接在 90 秒后关闭,那是因为服务器随后关闭了空闲连接。服务器就是这么做的。除了在服务器终止连接之前再次使用连接之外,您无法以任何其他方式阻止它们。

TCP保活

TCP keepalive 选项处于完全不同的级别。这基本上是 TCP 在 N 秒不活动后通过连接发送数据包,以确保连接保持活动状态(并检测断开的连接)。

libcurl 默认情况下不启用 TCP keepalive,请参阅CURLOPT_TCP_KEEPALIVE。

  • (偏离原来的问题)TCP keepalive 是由 TCP 堆栈完成的,curl 无法显示它们。我建议使用 Wireshark 来监听和分析流量。 (2认同)