无法使用POCO获得并发HTTPS请求

Can not get concurrent HTTPS requests work with POCO

本文关键字:并发 HTTPS 请求 POCO      更新时间:2023-10-16

我想使用Poco(1.6.0)并发地向同一端点发送一些https请求,但我不断得到与我所做的代码异常。(然而,使用HTTP请求的相同代码可以完美地工作…)

下面是我使用的代码:
Poco::Net::initializeSSL();
try {
   Poco::URI ep("https://stackoverflow.com/");
   Poco::SharedPtr<Poco::Net::InvalidCertificateHandler> ptrHandler
         = new Poco::Net::AcceptCertificateHandler(false);
   Poco::Net::Context::Ptr context = new Poco::Net::Context(Poco::Net::Context::CLIENT_USE,
                                                   "", "", "", Poco::Net::Context::VERIFY_STRICT,
                                                   9, true, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
   Poco::Net::SSLManager::instance().initializeClient(0, ptrHandler, context);
   for (int i = 0; i < 20; ++i)
   {
      // Start an asynchronous HTTPS request
      std::future<bool> f = std::async(std::launch::async, []() -> bool {
                  try {
                     Poco::URI ep("https://github.com/");
                      std::unique_ptr<Poco::Net::HTTPSClientSession> session(
                               new Poco::Net::HTTPSClientSession (ep.getHost(), ep.getPort()) );
                      Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET,
                                             ep.getPathAndQuery() ,
                                             Poco::Net::HTTPMessage::HTTP_1_1);
                      request.write(std::cerr);
                      try {
                        session->sendRequest(request);
                      }
                      catch (const Poco::Exception& e) {
                         std::cerr << "Error A" << std::endl;
                         std::cerr << e.code() << " - " << e.displayText() << std::endl;
                         throw;
                      }
                      Poco::Net::HTTPResponse response;
                      try {
                        session->receiveResponse(response);
                      }
                      catch (const Poco::Exception& e) {
                         std::cerr << "Error B" << std::endl;
                         std::cerr << e.code() << " - " << e.displayText() << std::endl;
                         throw;
                      }
                      response.write(std::cerr);
                      std::this_thread::sleep_for(std::chrono::seconds(1));
                     std::cerr << "Async request ended" << std::endl;
                  }
                  catch (const Poco::Exception& e) {
                     std::cerr << "Error :-/" << std::endl;
                     std::cerr << e.code() << " - " << e.displayText() << std::endl;
                     throw;
                  }
                  std::cerr << "Async request ended 2" << std::endl;
                  return true;
      });
      // Generate several HTTPS requests until the async request is completed
      std::chrono::microseconds span (10);
      while (f.wait_for(span) != std::future_status::ready)
      {
         std::unique_ptr<Poco::Net::HTTPSClientSession> session(
                  new Poco::Net::HTTPSClientSession (ep.getHost(), ep.getPort()) );
         Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET,
                                 ep.getPathAndQuery() ,
                                 Poco::Net::HTTPMessage::HTTP_1_1);
         request.write(std::cerr);
         try {
            session->sendRequest(request);
         }
         catch (const Poco::Exception& e) {
            std::cerr << "Error 1" << std::endl;
            std::cerr << e.code() << " - " << e.displayText() << std::endl;
            throw;
         }
         Poco::Net::HTTPResponse response;
         try {
            session->receiveResponse(response);
         }
         catch (const Poco::Exception& e) {
            std::cerr << "Error 2" << std::endl;
            std::cerr << e.code() << " - " << e.displayText() << std::endl;
            throw;
         }
         response.write(std::cerr);
      }
      f.get();
   }
}
catch (const Poco::Exception& e) {
   std::cerr << "ERROR :-(" << std::endl;
   std::cerr << e.code() << " - " << e.displayText() << std::endl;
}
Poco::Net::uninitializeSSL();

这是我得到的问题:

当我在QtCreator调试器中运行代码时,我得到了以下一个:一旦异步请求结束,主线程中的当前请求抛出Poco异常。

Error 1
4 - I/O error: Interrupted

然而,这似乎不会出现在QtCreator调试器之外。这有点奇怪。

这可能是并发问题,但我找不到我做错了什么,我没有在互联网上看到任何类似的问题。你能帮我找出我的错误吗?

谢谢。

EDIT:简化了最小的代码,并在问题描述中添加了一些细节。

EDIT2:似乎我忘了提到最重要的信息,我得到这个问题的环境。Ubuntu 14.04 LTS 64位,gcc 4.8.4, gdb 7.7.1, openssl 1.0.1f

问题来自于太旧的GDB版本。在其7.9版本中,GDB提供了许多与多线程调试相关的改进,并且可以用于调试此代码而不会出现任何问题旧版本的GDB 使用此代码将失败