我正在尋找一種方法來訪問&篡改由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
...和代理服務器呢?我在一個新的答案中解釋得更好... –