使用Qt / QNetworkAccessManager区分连接超时和网络读取超时

时间:2020-08-05 22:48:14

标签: qt qtwebkit qtnetwork

我正在使用QtWebKit(Qt5)(这是我的新手)来加载需要测量大量网站行为/状态的项目的网页。这包括渲染这些站点,所以我选择Qt来完成任务,因为它提供了一个轻松的界面来渲染和捕获页面中的图像。

我遇到的问题是我一生无法解决如何区分连接超时和套接字读取超时,特别是当服务器在连接后再也没有发送任何数据时的套接字读取超时建立了

所以这两种情况是:

  1. 尝试将GET请求发送到www.filtered.com,防火墙将丢弃所有没有有效拒绝的数据包。连接永远不会完成,在阻止尝试建立连接时会触发超时
  2. 尝试将GET请求发送到www.hungbrokenserver.com,连接几乎立即完成,但是没有响应返回到请求。尝试从套接字读取时发生超时

我正在使用信号来捕获错误。这些确实使我能够捕获诸如连接被拒绝或SSL协议问题之类的事情。但是我看不到有一种方法可以使用connect()来判断read()超时和QNetworkReply::TimeoutError超时之间的区别,因为它在两种情况下都可以触发,并且看起来完全一样

从高级方法的角度来看,我意识到有一些解决问题的problem回方式不像接收“连接超时”信号那样简单

例如,如果我能以某种方式在连接完成时收到信号,则可以将标志标记为“连接成功”,然后稍后确定是由于连接还是读取而导致发生超时(如果我也当我从服务器收到第一个字节时,标记一个标记)

我正在使用类似以下代码的东西-它很漂亮。有了这个,我可以发现诸如连接被拒绝,错误的SSL协议交换,甚至是第7层故障(各种HTTP响应代码都被认为是错误)之类的东西

   app.connect(page.networkAccessManager(),
              &QNetworkAccessManager::finished,
              &main,
              &MyClass::do_finished);
   ...

   QNetworkReply* reply = manager.get(QNetworkRequest(req));

在我的do_finished函数中,我有基本的逻辑来检查信号是否是错误的结果:

MyClass::do_finished(QNetworkReply* r)
{
  g_finished_count++;

  if (!g_finished_count) {
      DEBUG("First network event completed!");
      if (r->error()) {
      DEBUG("First network event finished with an error");
      if (r->error() == QNetworkReply::ConnectionRefusedError) {
          g_connection_refused = true;
          return;
      }

      qDebug() << r->errorString();
      qDebug() << r->readAll();
      switch (r->error()) {
        case QNetworkReply::ConnectionRefusedError:
          DEBUG("Connection refused");
          first_error = NoService;
          break;
        case QNetworkReply::TimeoutError:
            DEBUG("Timeout occurred");
        ...

我尝试使用QTimer并使用QNetworkAccessManager()->connectToHost函数自己来处理get()函数的连接部分,但是没有办法在{{1 }}完成后,对于已过滤的服务和接受连接但不发送数据的服务,其行为是完全相同的

我看到Qt 5.15(connectToHost)中添加了一种设置QNetworkAccessManager超时的新方法,但是我不清楚这是否提供了解决问题的机制-但我无法做到。强制在我所有的服务器上都升级到该版本,因为大多数发行版似乎都没有达到Qt的最高水平

我仍然无法确定这两种情况之间的区别,因为错误被设置为“取消操作”,无论它是在封面的QNetworkAccessManager.setTransferTimeout还是connect()中被阻止

那我想念什么?如何确定超时是连接超时导致的结果还是连接等待服务器中的数据超时而导致的成功?我很确定没有专门用于此目的的信号,但是也许我没有看到解决方法?

注意:我意识到我可以在执行HTTP请求之前使用单独的基本TCP连接,但这并不是一个完美的解决方案,并且需要额外的连接。看来这应该是不必要的...

0 个答案:

没有答案