有没有办法可以在C ++中取消 curl_easy_perform ?
我有一个场景,我尝试连接到离线的网络资源,curl_easy_perform在返回 CURLE_COULDNT_CONNECT 之前需要一定的时间。 但与此同时,用户已关闭了希望连接的UI,我希望immediatley切断卷曲连接,而不必等待它无法连接。
我已经尝试存储我使用的卷曲指针:
CURL *pEasy = curl_easy_init ();
然后在做curl_easy_perform时我打电话给
curl_easy_cleanup(pEasy);
试图释放或“停止”卷曲连接但是它崩溃了,我从 curl_easy_perform 中收到以下错误:
Unhandled exception at blah blah: Access violation reading location 0x00000004.
有没有办法可以取消连接尝试???? 我已经阅读了这个链接:How can I immediately cancel a curl operation?但它似乎处理成功连接后取消卷曲连接。
编辑 - 解决方案
我发现如果我打电话:
curl_easy_reset( pEasy );
然后
curlResult = curl_easy_perform ( pEasy );
几乎立即返回结果 CURLE_OPERATION_TIMEDOUT 。
我认为这就是我所需要的:)
答案 0 :(得分:1)
您可以事先设置connection timeout,而不是取消尝试。 :
curl_easy_setopt(pEasy, CURLOPT_CONNECTTIMEOUT, 5);
答案 1 :(得分:1)
您可以在一个帖子中运行curl_easy_perform并保留CURL
对象。
每当要关闭连接时,在CURL对象上调用curl_easy_setopt(m_chatCurl, CURLOPT_TIMEOUT_MS, 1)
。
这样连接就会超时,线程就能完成。
答案 2 :(得分:0)
虽然更改超时选项很好,因为它可能只是转发给套接字本身,但我认为最好只是关闭套接字。
>void terminateConnectionNow(CURL* curlHandle)
{
curl_socket_t sockfd;
auto res = curl_easy_getinfo(curlHandle, CURLINFO_ACTIVESOCKET, &sockfd);
// ASSERT_EQ(res, CURLE_OK); - no point in doing anything if the socket is not there
closesocket(sockfd);
}
关闭套接字可确保完全断开连接,无论它处于连接,发送,接收等状态如何,因此在最后一刻都没有连接的机会。
与curl_easy_cleanup
相反,即使该操作是从另一个线程执行的,curl也不会崩溃-sockets
本身是由操作系统管理的,因此关闭套接字是线程安全的。然后,可以适当地防止curl受到套接字操作的错误影响。手动关闭套接字后,诸如curl_easy_recv
之类的操作只会返回错误代码,例如:CURLE_RECV_ERROR
。
访问curl-options和读取套接字句柄可能看起来像是危险的操作,因此设置超时也是如此。但是,在读取套接字句柄时,不会修改curl的状态,只读取缓存的套接字,因此我认为它是更安全的选择。
为了安全起见,您可以获取带有回调的套接字并将其存储在一边,因此您可以从另一个线程访问它,而无需完全触摸卷曲句柄。您可以看到这种方法here。
当然,关闭插槽并不意味着卷曲的手柄已关闭。 curl句柄仍然存在,您仍然需要确保用curl_easy_cleanup
销毁了该句柄-但在确保所有线程都无法通过其connect / send / recv操作失败并留下curl句柄之前,否则无需这样做,否则会有访问冲突的风险。