gpt4 book ai didi

c++ - QNetworkAccessManager 从不发出 finished() 信号

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:24:16 25 4
gpt4 key购买 nike

我正在为一个项目开发一个模块,其中使用 HTTP GET 请求检索一些 XML 数据,然后将其转换为另一种格式并发送到子系统。

到目前为止我写的代码如下:

CMakeLists.txt:

project(HttpDemo)
cmake_minimum_required(VERSION 2.8)
set(CMAKE_BUILD_TYPE Debug)

#find_package(Qt5Widgets)
find_package(Qt5Core)
find_package(Qt5Network)

set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)

aux_source_directory(. SRC_LIST)
add_executable(${PROJECT_NAME} ${SRC_LIST})
qt5_use_modules(${PROJECT_NAME} Core Network) #Gui Widgets

main.cpp

#include <QtCore>
#include <QtNetwork>

class HttpHandler : public QObject
{
Q_OBJECT
public:
HttpHandler(QObject* parent=Q_NULLPTR) : QObject(parent)
{
QObject::connect(&nm, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
qDebug() << QSslSocket::sslLibraryBuildVersionString();
}
private:
QNetworkAccessManager nm;
public slots:
void post(QString urlLink)
{
QUrl url(urlLink);
QNetworkRequest request(url);
QSslConfiguration sslConf;
sslConf.setProtocol(QSsl::SslV3);
request.setSslConfiguration(sslConf);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencded");

QUrlQuery query;
query.addQueryItem("client_id", "1234");
query.addQueryItem("code", "abcd");

QUrl params;
params.setQuery(query);

nm.post(request, params.toEncoded());
}

void get(QString urlLink)
{
QUrl url(urlLink);
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");

nm.get(request);
}

void replyFinished(QNetworkReply* reply)
{
QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
if(statusCode.isValid())
{
// Print or catch the status code
QString status = statusCode.toString(); // or status_code.toInt();
qDebug() << status;
qDebug() << QString::fromStdString(reply->readAll().toStdString());
}
}
};

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

HttpHandler hh;
hh.get("SOME_URL");

return a.exec();
}

#include "main.moc"

使用 SOME_URL 我已经尝试了很多链接,所有这些链接都没有任何问题,比如 Firefox 的 Http Requester 插件。我得到:

"OpenSSL 1.0.1j 15 Oct 2014"

qt.network.ssl: QSslSocket: cannot resolve SSLv2_client_method

qt.network.ssl: QSslSocket: cannot resolve SSLv2_server_method

根据网上的权威说法,这应该不是问题。有一件事是肯定的——我的 replyFinished(QNetworkReply*) 插槽没有被触发,尽管它连接到 QNetworkAccessManagerfinished() 信号>。这意味着无论出于何种原因未发出信号。将 QSslConfiguration 更改为不同的 QSsl::SslProtocol 不会对结果产生影响。


更新(根据评论中的要求):

以下代码使用 readyRead() 和动态分配的回复。结果 - 与上述相同。

#include <QtCore>
#include <QtNetwork>

class HttpHandler : public QObject
{
Q_OBJECT
public:
HttpHandler(QObject* parent=Q_NULLPTR) : QObject(parent)
{
qDebug() << QSslSocket::sslLibraryBuildVersionString();
this->manager = new QNetworkAccessManager(this);
this->reply = Q_NULLPTR;
}
private:
QNetworkAccessManager* manager;
QNetworkReply* reply;
signals:
void finished();
public slots:
void post(QString urlLink)
{
QUrl url(urlLink);
QNetworkRequest request(url);
QSslConfiguration sslConf;
sslConf.setProtocol(QSsl::SslV2);
request.setSslConfiguration(sslConf);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");

QUrlQuery query;
query.addQueryItem("client_id", "1234");
query.addQueryItem("code", "abcd");

QUrl params;
params.setQuery(query);

manager->post(request, params.toEncoded());
}

void get(QString urlLink)
{
QUrl url(urlLink);
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");

this->reply = manager->get(request);
QObject::connect(reply, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));
}

void slotReadyRead()
{
qDebug() << "Hello"; // I never land here
}

void replyFinished(QNetworkReply* reply)
{
QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
if(statusCode.isValid())
{
QString status = statusCode.toString(); // or status_code.toInt();
qDebug() << status;
qDebug() << QString::fromStdString(reply->readAll().toStdString());
}

emit finished();
}
};

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

HttpHandler *hh = new HttpHandler(&a);
QObject::connect(hh, SIGNAL(finished()), &a, SLOT(quit()));

hh->get("http://httpbin.org/ip"); // or any other httpbin.org endpoint

return a.exec();
}

#include "main.moc"

更新 2:

我刚找到一个 example in the Qt documentation .下载、编译并运行了这个东西——同样的错误,但它有效。

最佳答案

问题已解决(参见 here)。基本上问题出在公司的代理上。我的一位同事尝试了一下,将 HTTP 替换为 HTTPS(即使链接是 HTTP),并且它突然起作用了。然后它让我们震惊 - 公司的代理缓存 HTTP(也做其他事情),这会导致巨大的延迟,如果超时容忍度足够小,QNetworkAccessManager 将返回套接字超时。

使用 QNetworkProxyFactory::setUseSystemConfiguration(true) 启用代理的方式不会使您的应用程序依赖于代码中的配置,而是系统的配置。

关于c++ - QNetworkAccessManager 从不发出 finished() 信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46709752/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com