尝试连接时取消curl_easy_perform
Cancel curl_easy_perform while it is trying to connect
有没有办法取消C++中的curl_easy_performance??
我有一个场景,我试图连接到脱机的网络资源,curl_easy_perform需要一定的时间才能返回CURLE_COULDNT_connect。但与此同时,用户已经关闭了希望连接的UI,我想立即切断curl连接,而不必等待它无法连接。
我已经尝试存储我使用的卷曲指针:
CURL *pEasy = curl_easy_init ();
然后当它执行curl_easy_perform时,我打电话给
curl_easy_cleanup(pEasy);
在试图释放或"停止"卷曲连接时,它崩溃了,我从curl_easy_performance得到了以下错误:
Unhandled exception at blah blah: Access violation reading location 0x00000004.
有没有办法取消连接尝试????我读过这个链接:如何立即取消卷曲手术?但它似乎可以在成功连接后取消卷曲连接。
编辑-解决方案
我发现,如果我打电话:
curl_easy_reset( pEasy );
然后
curlResult = curl_easy_perform ( pEasy );
几乎立即返回结果CURLE_OPERATION_TIMEDOUT。
我想这就是我需要的:)
您可以在线程中运行curl_easy_perform并保留CURL
对象。
在CURL对象上,只要您想关闭连接,就调用curl_easy_setopt(m_chatCurl, CURLOPT_TIMEOUT_MS, 1)
。
通过这种方式,连接将超时,线程将能够完成。
您可以预先设置连接超时,而不是取消尝试,例如:
curl_easy_setopt(pEasy, CURLOPT_CONNECTTIMEOUT, 5);
虽然更改超时选项很可能很好,因为它可能 关闭插座可以确保连接完全断开,无论它在哪里连接、发送、接收等,因此在最后一刻都没有连接的机会。 与 虽然访问curl选项和读取套接字句柄看起来可能是一个有风险的操作,但设置超时也是如此。然而,当读取套接字句柄时,curl状态不会被修改,只读取缓存的套接字,所以我认为这是一个更安全的选项。 为了完全安全,您可以通过回调获得套接字并将其存储在一边,这样您就可以从另一个线程访问它,而无需接触curl句柄。你可以在这里看到这种方法。 当然,关闭插座并不意味着卷曲手柄关闭。curl句柄仍然有效,您仍然需要确保使用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_easy_cleanup
销毁该句柄,但在确保所有线程的connect/send/recv操作失败并保留curl句柄之前,否则您将面临访问冲突的风险。