我正在寻找一种方法来访问&篡改由Qt应用程序发送和接收的原始数据包数据,但找不到任何东西。有什么方法吗? 或者如果不是,应用程序至少有一种方法来从QWebView访问分组数据。从Qt应用程序获取原始数据包数据
有没有什么方法可以实现上述任何一种?
我正在寻找一种方法来访问&篡改由Qt应用程序发送和接收的原始数据包数据,但找不到任何东西。有什么方法吗? 或者如果不是,应用程序至少有一种方法来从QWebView访问分组数据。从Qt应用程序获取原始数据包数据
有没有什么方法可以实现上述任何一种?
对不起,萨姆,我不能让它工作。我一直在尝试我能想象到的一切,但没有任何事情会像预期的那样。
让我们的选项的短名单,并能做什么和不能做:
您可以通过获取QWebFrame
与webView->page()->currentFrame()
,然后接入到方法,如setContents()
的方式访问所检索的网页,setHtml()
,toHtml()
或toPlainText()
。您可以通过这些功能动态更改小部件中显示的网页。
您可以通过replyFinished()
插槽中的方法reply->readAll()
访问为每个请求接收到的原始响应(以字节数组形式)。
通过覆盖您自己的网络访问管理器中的QNetworkAccessManager::createRequest()
方法,可以拦截请求。您可以访问请求中发送的URL和标题,并更改它们或取消请求。
但是......你要访问的请求和回答数据每个请求。
访问请求很简单,它已被解释为自定义QNetworkAccessManager
中的createRequest()
方法。但是,让我们来谈谈其他部分:
对于我所看到的,从请求得到的答复是只读的和IT不能改变,因为它是在硬编码源代码为QNetworkReply
。
您不能使用的writeData()
功能QNetworkReply
,因为它是硬编码简单地做return -1
!
您可以尝试继承自己的QNetworkReply
,然后将其返回到自定义QNetworkAccessManager
的createRequest()
方法中。您必须覆盖功能readAll()
,bytesAvailable()
和abort()
。奇怪的是,这个方法只有在请求发送到非HTTP目的地时才起作用。我认为QNetworkAccessManager
的内部调用QNetworkReply
的不同实现取决于所使用的协议(HTTP,FTP,...)。所以这在某种意义上是有效的,但不是我们想要的方式。例如,此方法可用于在特定条件下返回预定义的网页。
考虑到QNetworkAccessManager::createRequest()
必须返回QNetworkReply
对象的事实,我看不到允许在回复的字节数组中篡改的子类化的任何组合。它受到很好的保护,您必须重新实现这些类上的所有内容才能实现您的目标。几乎复制粘贴所有QtNetwork
零件的源类并自行实施。
所以我认为,答案是:“不,似乎它不能完全按照自己的要求进行;只有部分”。
对不起。
它看起来像你想要的Wireshark http://www.wireshark.org/或Fiddler http://www.fiddler2.com/fiddler2/,或者甚至查尔斯http://www.charlesproxy.com/。
这些工具与Qt没有任何关系,可用于检查和拦截各种程序的网络流量。
在网络连接中篡改与服务器之间发送/接收数据的正确方法是使用QNetworkAccessManager
。
这个类可以让你发送一个请求给服务器(可能带有头文件)并获得响应(也包含头文件)。
您可以访问相应的QNetworkReply
对象上收到的数据。响应也标题:
{
...
QNetworkAccessManager *qnam = new QNetworkAccessManager(this);
connect(qnam, SIGNAL(finished(QNetworkReply*)),
this, SLOT(replyFinished(QNetworkReply*)));
QNetworkRequest request;
request.setUrl(QUrl("http://stackoverflow.com"));
request.setRawHeader("User-Agent", "Foo browser");
qnam->get(QNetworkRequest(request));
...
}
然后定义槽:
void MyWidget::replyFinished(QNetworkReply *reply)
{
QByteArray response = reply->readAll();
QString mime = reply->header(QNetworkRequest::ContentTypeHeader).toString();
...
}
事实上,一个QWebView
有一个QNetworkAccessManager
对象来执行请求和管理回复。您可以通过QWebPage::networkAccessManager()
方法获取该对象。您可以通过QWebView::page()
从QWebView
获取QWebPage
。
编辑
要操纵由QWebView
显示网页时,可以直接通过webView->setHtml(QString html)
来设定一个新的HTML内容。
您也可以通过QWebFrame
类的方法直接访问HTML。
为了获得这样的对象,你必须做到:
QWebFrame *wb = webView->page()->currentFrame();
的方法是:
void QWebFrame::setContent (const QByteArray & data, const QString & mimeType = QString(), const QUrl & baseUrl = QUrl())
在字节数组设置一个新的文档。
也是这样,但考虑到内容是一个HTML文档。
QString QWebFrame::toHtml() const
以获取HTML文档的内容。
QString QWebFrame::toPlainText() const
与上面相同,为纯文本。
查看这些功能的文档。
编辑2:
最后,如果要访问或过滤由QWebView
自身提出的要求,我可以看到只有一条路:从QNetworkAccessManager
派生类和覆盖所使用的方法提出请求并接收答案。
然后,将该类的实例设置为QWebView使用的QNetworkAccessManager。
让我有骨架澄清:
class MyNAM : public QNetworkAccessManager
{
// ...
MyNAM(QObject *parent = 0) : QNetworkAccessManager(parent) { }
// ...
virtual QNetworkReply * createRequest(Operation op, const QNetworkRequest & req, QIODevice * outgoingData = 0) {
// e.g. logging of the request
// e.g. decide if the request must be made
if (some_bool_deciding) {
QNetworkAccessManager::createRequest(op, req, outgoingData);
}
else {
// or faked...
}
// etc.
}
// ...
};
在主应用程序,你必须做:
// ...
MyNAM *nam = new MyNAM();
webview->page()->setNetworkAccessManager(nam);
// ...
从现在开始,所有的请求都将使用该对象进行。
此方法允许完全控制导航器所做的请求:筛选和访问请求数据(标题,取值和后置值等)。您可以记录请求,分析请求和他们的POST/GET字段等。
希望终于有所帮助!
所以这里是我做的 'QNetworkAccessManager * manager = ui-> webView-> page() - > networkAccessManager(); (经理,SIGNAL(完成(QNetworkReply *)),这个,SLOT(完成(QNetworkReply *))); void MainWindow :: finished(QNetworkReply * reply) { qDebug()<
数据由slot函数内的'reply-> readAll()'返回。看看我的插槽功能。 'QByteArray'是原始响应(字节数组)。您可以根据需要操纵收到的“QByteArray”。 –
是的,我可以但我想操纵QWebView显示的内容。即使我操纵槽功能中的回复,它也不会反映在QWebView中。 – Sam
...和代理服务器呢?一个良好的睡眠让我想到了这种可能性。
您可以在loopback example和torrent client example之间创建一个。因此,您可以捕获和篡改请求和的答复。
您可以使用webView->page()->networkAccessManager()->setProxy()
在客户端QWebView
上配置代理。
这涉及到建立一个进程来监听所需的端口(例如8080)并监听本地主机上的连接。
您必须实现代理的由协议:
在这里我没有经验,但路径似乎很清楚。这将是很多编码,但我认为这是一个很好的选择如果不是唯一选项。
更重要的是:它可以做到!
当然,可以使用代理服务器来完成。我曾经想过,但我也认为它可以在QT应用程序本身内完成。但事实并非如此,所以这让我别无选择,只能使用代理服务器。谢谢! – Sam
我不明白你的意思。你正在编写一个Qt应用程序,需要访问“原始数据包”吗?你的意思是什么“原始数据”? – Mat
我的意思是说,我用QWebView制作了一个浏览器。现在,无论何时QWebView从互联网上下载/上传数据,我都想访问发送和接收的http数据包数据,并篡改它。可能吗? – Sam
...和代理服务器呢?我在一个新的答案中解释得更好... –