c++ - 我怎么知道 QNetWorkReply 来自哪个代理?
问题描述
这是一种HTTP请求发送方法。当目标网站响应时,将调用 httpFinished()。
void HTTPClientBase:: HttpRequestGet()
{
network_manager.setProxy(proxy);
QNetworkRequest network_request;
network_request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
network_request.setUrl(URL);
reply = network_manager.get(network_request);
connect(reply, SIGNAL(finished(QNetWorkReply*)), this, SLOT(httpFinished(QNetWorkReply*)));
}
void HTTPClientBase::httpFinished(QNetWorkReply* reply)
{
// How do I know this reply comes from which proxy?
}
我可以循环调用 HttpRequestGet() 。
static HTTPClientBase myClient;
for(int i=0; i<20; i++)
{
myClient.setUrl("https:\\www.google.com");
myClient.setProxy("123.123.123.123:1234"); // The proxy changes every time in this loop.
myClient.HttpRequestGet();
}
什么时候HTTPClientBase::httpFinished(QNetWorkReply* reply)
被调用,我怎么知道这个回复来自哪个代理?}
解决方案
根据QNetworkReply文档,您可以使用成员函数QNetworkReply::request()获取相应的请求。
无论如何,QNetworkRequest 没有setProxy
.
但是,如果您正在为QNetworkAccessManager设置代理,则可以通过QNetworkReply::manager()获得指向相应管理器的指针。
注意连接命令。finished()
没有QNetworkReply*
参数,因此您的connect
命令也将失败,您必须更改HTTPClientBase::httpFinished(QNetWorkReply* reply)
为HTTPClientBase::httpFinished()
.
...
connect(reply, SIGNAL(finished()), this,
SLOT(httpFinished()));
}
void HTTPClientBase::httpFinished()
{
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
if(reply){
QNetworkAccessManager * manager = reply->manager();
QNetworkProxy proxy = manager->proxy();
// now you have the proxy
}
}
如您所见,您必须使用sender()来获取实际的信号发送者。您需要为您拥有的每个代理创建不同的QNetworkAccessManager实例。如果您有代理池,请先创建您的QNetworkAccessManager实例,然后根据您的特定需求选择它们。
如果您不想为每个代理创建一个新的 QNetworkAccessManager,您可以执行以下操作:
void HTTPClientBase:: HttpRequestGet()
{
network_manager.setProxy(proxy);
QNetworkRequest network_request;
network_request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
network_request.setUrl(URL);
reply = network_manager.get(network_request);
//new member variable: QHash<QNetworkReply*,QString> m_RequestToProxy;
m_RequestToProxy.insert(reply,proxy);
connect(reply, SIGNAL(finished()), this, SLOT(httpFinished()));
}
void HTTPClientBase::httpFinished()
{
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
if(reply){
QString proxy = m_RequestToProxy.take(reply);
//check if proxy is valid
//and then do whatever you want
}
}
另一个更好的解决方案是设置回复属性并将其放入槽中。
void HTTPClientBase:: HttpRequestGet()
{
network_manager.setProxy(proxy);
QNetworkRequest network_request;
network_request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
network_request.setUrl(URL);
reply = network_manager.get(network_request);
reply->setProperty("_proxy_",proxy);
connect(reply, SIGNAL(finished()), this, SLOT(httpFinished()));
}
void HTTPClientBase::httpFinished()
{
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
if(reply){
QVariant v_proxy = reply->property("_proxy_");
//check if proxy is valid
if(v_proxy.isValid()){
QString proxy = v_proxy.toString();
//and then do whatever you want
}
}
}
推荐阅读
- php - 缺少作者;谷歌网站管理员工具中缺少更新
- c# - 从属性中获取属性的名称
- c# - DataGridViewComboBoxColumn 中的选定项目始终检索第一个值
- android - Uri 和 WebView 类以不同方式解析包含权限(主机或用户信息)中的反斜杠的 URL
- python - 如何使用python从cloudformation堆栈字典中获取特定字段的值
- php - 如何使用 Yii2 kartik-mpdf 添加水印
- c# - 有办法发送所有完整选项出现在 firebase 云消息传递创建消息页面
- php - 使用 $wpdb->prepare 查询 IN 子句
- c# - 无法访问数组中抽象类实例的字段
- xml - VB.net XML 到 DataSet - 不同 DataTables 项之间的关系