【发布时间】: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¶m2=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