【问题标题】:Closing connections handled by QNetworkAccessManager关闭由 QNetworkAccessManager 处理的连接
【发布时间】:2014-07-07 07:55:52
【问题描述】:

所以我正在为嵌入式设备开发一个 Web 应用程序,它使用 QNetworkAccessManager 从 Web 服务器检索信息。每个请求都是一个 GET 请求,它调用一个 PHP 页面,在 url 中有一些参数。 PHP 脚本的输出是我的应用请求的信息。

整个过程非常简单,可以简化到这几行代码:

void fetch() {
    Q_ASSERT(m_reply == 0);
    QUrl url = QUrl("http://subdomain.myserver.com/info.php?param1=1&param2=2");
    m_reply = m_qnam->get(url);

    connect (m_reply, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
    connect (m_reply, SIGNAL(finished()), this, SLOT(onFinished()));
}

void onReadyRead() {
    m_contents.append(m_reply->readAll());
}

void onFinished() {
    m_reply->deleteLater();
    m_reply = 0;
    // do something with the contents
    m_contents.clear();

   // fetch again
   fetch();
}

m_qnam 是一个 QNetworkAccessManager 实例,m_contents 是一个 QByteArray。

这很好用,但是在尝试数百个此类请求时遇到问题,最终我从服务器 (Apache) 收到 429 错误(来自同一 IP 的连接太多)。要从中恢复,我必须断开与互联网的连接并重新连接(这给了我一个新的 IP 地址)。

我可以增加 Apache 上的最大连接数,但是我相信 TCP 连接应该在 QNetworkReply 被删除后立即关闭,但事实并非如此。由于我一次只下载固定数量的请求(这由我的应用程序上的排队系统控制,并且 QNetworkAccessManager 也有最大同时下载数量),我不认为调整 Apache 是答案。

TCP连接似乎没有正确关闭。

所以我的问题是:

如何确保下载完成后与我的服务器的每个连接都正确关闭。 QNetworkAccessManager 应该处理这个吗?这是一个错误吗?我应该与我的服务器建立自己的自定义 TCP 连接并在整个应用程序期间保持一定数量的连接吗?如果是这样,我应该从哪里开始?

谢谢,我们将不胜感激。

Qt 5.3/OSX/iOS

注意:修改了我的问题以符合 Pavel 的评论。一次只有一个请求处于活动状态。

【问题讨论】:

  • 如何存储插槽中使用的reply 变量?如果将所有回复对象存储在同一个变量中,则会丢失除最后一个之外的所有指针,因此不会读取和删除第一个回复。您可能希望将QNetworkAccessManager 的槽与QNetworkReply 参数一起使用,或者在槽内使用sender() 来检索正确的回复对象。

标签: apache tcp qnetworkaccessmanager


【解决方案1】:

回答我自己的问题:一旦删除 QNetworkReply,或者调用 abort() 或 close() 方法,QNetworkAccessManager 就会正确关闭所有连接。当然,这是以异步方式发生的。

我收到的错误来自对我的服务器施加的一些限制,这些限制只允许来自每个 IP 的一定数量的连续连接。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-16
    • 1970-01-01
    • 2011-09-27
    • 2019-09-21
    • 1970-01-01
    • 1970-01-01
    • 2013-06-28
    • 1970-01-01
    相关资源
    最近更新 更多