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

问题描述 投票:0回答:1

我如何保持与libcurl的连接活跃?

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

示例页面很棒,但是我看不到涉及Keep-Alive的页面:https://curl.haxx.se/libcurl/c/example.html

我确实找到了CURLOPT_TCP_KEEPINTVLhttps://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);
}

描述如下:

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

两个问题:

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

curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postthis);
res = curl_easy_perform(curl);

无论何时我想要POST更多数据并将其发送到同一连接中,或者还有更多数据吗?

B)这些keepalive探针是什么,我在哪里可以阅读更多有关它们的信息?这是OS在我身后做的事情吗?我应该认为这是:从我的应用程序的角度来看,该连接神奇地活跃起来,我不必为此担心吗?

c libcurl
1个回答
-1
投票

libcurl依赖于操作系统的TCP keepalive功能。如果操作系统支持它,那么当请求保持活动状态的TCP连接时,libcurl会简单地打开套接字,然后告诉操作系统通过所需的API使连接保持活动状态,并指定请求的时间间隔和空闲时间。

例如,在Linux中,这是通过setsockopt()系统调用完成的。如果在setsockopt()下运行程序,则会注意到多个strace系统调用来为套接字设置指定的选项:

setsockopt()

根据描述,只要我保持范围内的卷曲,连接就将保持打开状态。它是否正确?

您无需将“ $ strace -e setsockopt ./program >/dev/null setsockopt(4, SOL_TCP, TCP_NODELAY, [1], 4) = 0 setsockopt(4, SOL_SOCKET, SO_KEEPALIVE, [1], 4) = 0 setsockopt(4, SOL_TCP, TCP_KEEPIDLE, [120], 4) = 0 setsockopt(4, SOL_TCP, TCP_KEEPINTVL, [60], 4) = 0 保留在范围内”即可正常工作,所有操作均由操作系统处理。从创建curl句柄的那一刻起,该句柄将与TCP套接字关联,并且libcurl将在假设操作系统保持连接活动的情况下继续使用同一套接字。如果libcurl检测到由于某种原因关闭了连接(例如,由于keepalive超时已到期,则操作系统关闭了连接),它将返回相应的错误或只是重新打开连接。

然后,我想张贴更多数据时,我应该继续做[...]并将其发送到同一连接中,或者还有更多数据吗?

是。实际上,仅此而已,所有工作都由内核在后台完成。

这些keepalive探针是什么,我在哪里可以阅读到更多关于它们的信息?

Keepalive探针是非常简单的TCP数据包,没有数据。当服务器接收到数据包时,根据TCP规范,它将需要通过发回一个空的ACK数据包来确认它,这就是使连接保持活动状态的方式。您可以阅读更多CURL*或仅搜索“ TCP keepalive”。

这是操作系统在我身后做的事情吗?

是的,正如我上面所解释的。

我应该这样认为:从我的应用程序的角度来看,该连接神奇地活跃起来,我不必为此担心吗?

确实,这正是您应该做的。

© www.soinside.com 2019 - 2024. All rights reserved.