Libcurl 停止工作,SSL 连接错误

Libcurl stops working, SSL connect error

我正在开发一个供个人使用的程序,该程序会定期抓取一些网页。其中一个需要使用 SSL,它的主要 URL 实际上是一个负载均衡器,每次都重定向到一个不同的域,这是少数几个(不确定这是否相关)。我对 libcurl 和 SSL 特别陌生,所以我可能遗漏了一些明显的东西,但我不这么认为。

该程序在一段时间内运行良好(到目前为止,从未超过一个小时)但是一旦它第一次遇到 SSL 连接错误,它就会每次都给出相同的错误。在它开始失败之前,总是有不同的时间量和不同数量的成功请求。

错误缓冲区始终包含以下内容:schannel: next InitializeSecurityContext failed: SEC_E_ILLEGAL_MESSAGE (0x80090326) - This error usually occurs when a fatal SSL/TLS alert is received (e.g. handshake failed). More detail may be available in the Windows System event log.

eventvwr 中没有任何有用的内容。对该错误代码 return 的搜索结果与早期版本 Windows 服务器上的自签名证书有关,但除此之外几乎没有其他问题。我无法控制我连接的服务器,但我怀疑它是一个 Windows 框。

我 运行 没有想法,所以我将提供任何可能相关的细节。我真的不能 post 任何实际的源代码,因为我已经在几个 类 中抽象了所有 curl 调用,所以我必须粘贴大量样板代码才能让其他人理解它。不过,我已经通过 Visual Studio 调试器确认这就是实际调用的结果。

我在主线程中初始化 libcurl,然后再创建其他线程,如下所示:curl_global_init(CURL_GLOBAL_WIN32 | CURL_GLOBAL_SSL);

然后我在第二个线程中创建并初始化实际的 curl 句柄,并且仅在该线程中,如下所示:

m_handle = curl_easy_init();
curl_easy_setopt(m_handle, CURLOPT_WRITEDATA, this);
curl_easy_setopt(m_handle, CURLOPT_WRITEFUNCTION, write);
curl_easy_setopt(m_handle, CURLOPT_DEBUGDATA, this);
curl_easy_setopt(m_handle, CURLOPT_DEBUGFUNCTION, debug);
curl_easy_setopt(m_handle, CURLOPT_VERBOSE, 1);
curl_easy_setopt(m_handle, CURLOPT_ERRORBUFFER, &m_errormsg[0]);
curl_easy_setopt(m_handle, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(m_handle, CURLOPT_COOKIEFILE, "");

我试过将 CURLOPT_SSL_VERIFYHOSTCURLOPT_SSL_VERIFYPEER 都设置为 0,但这没有帮助。

我在 Visual Studio 2013 年用 nmake /f Makefile.vc mode=static VC=12 ENABLE_WINSSL=yes ENABLE_SSPI=yes MACHINE=x64 DEBUG=yescurl-7.43.0.tar.gz 构建了 libcurl。

这是怎么回事,我该如何解决?

CURL *handle = curl_easy_init();
char url[] = "https://google.com";
curl_easy_setopt(handle, CURLOPT_URL, url);
curl_easy_perform(handle);

应该可以...

我猜测您正在为所有请求使用单个 CURL 句柄(因为您说 "I create and initialize the actual curl handle")。该解决方案最有可能为每个使用 curl_easy_perform() 完成的请求创建一个 CURL 句柄,然后立即 curl_easy_cleanup() 它。

您所看到的可能是由于服务器关闭了 SSL 连接造成的。但是您的 CURL 句柄可能会保持其原样(即握手已完成),这不再合适。