gpt4 book ai didi

c++ - 如何立即取消 curl 操作?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:09:07 58 4
gpt4 key购买 nike

我正在使用 libcurl在 C++ 中,我使用 Boost.Thread 在与我的 UI 不同的线程中调用 curl_easy_perform .

主 UI 有一个取消按钮,我希望它能够完美响应(即,当用户点击它时,它应该立即使用react)。我已经设置了读取、写入和进度回调来读取原子 should_cancel 变量(如 this 问题),但有两个问题:

  1. 从按下取消到 curl 操作完成之间通常会有一个非常小的(但很明显)延迟。

  2. 有时会有很长的(有时是无休止的)延迟。在这种情况下,要么:

    一个。很长时间没有调用进度、读取和写入回调,或者

    b.进度回调 is 被调用,我返回一个非零值(意味着它应该终止),但是 curl 操作并没有完成一段时间(事实上,在此期间再次调用了进度函数!)

所以:

  1. 为什么会发生长时间的延迟(尤其是在没有调用进度函数的情况下)?
  2. 我应该怎么做才能让取消按钮正确 react ?

一种可能性是告诉 UI 取消操作成功,但在后台继续运行 curl 线程直到它取消。这个问题(我认为)是它强制 should_cancel 变量是全局的,而不是限定在操作开始的对话框中。

最佳答案

我在 curl 7.21.6 中遇到了同样的问题。当试图中止 smtp 协议(protocol)时。从读取回调返回 CURL_READFUNC_ABORT 会停止传输,但 curl_easy_perform 在接下来的 5 分钟内不会返回。可能是在等待 tcp 超时。

为了遍历它,我存储 curl 使用的套接字(替换 curl_opensocket_callback),并在需要时直接关闭此套接字。

curl_socket_t storeCurlSocket(SOCKET *data, curlsocktype purpose, struct curl_sockaddr *addr) {
SOCKET sock = socket(addr->family, addr->socktype, addr->protocol);
*data = sock;
return sock;
}

size_t abort_payload(void *ptr, size_t size, size_t nmemb, SOCKET *curl_socket) {
SOCKET l_socket = INVALID_SOCKET;
swap(l_socket, *curl_socket);
if (l_socket != INVALID_SOCKET) {
shutdown(l_socket, SD_BOTH);
closesocket(l_socket);
}
return CURL_READFUNC_ABORT;
}

...calling perform...
SOCKET curlSocket;
curet = curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, storeCurlSocket);
curet = curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, &curlSocket);
curet = curl_easy_setopt(curl, CURLOPT_READFUNCTION, abort_payload);
curet = curl_easy_setopt(curl, CURLOPT_READDATA, &curlSocket);
curet = curl_easy_perform(curl);
if (curet == CURLE_ABORTED_BY_CALLBACK) {
//expected abort
}
...

关于c++ - 如何立即取消 curl 操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4456180/

58 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com