Unsolved Qt get external IP address using QNetworkReply
-
Good day
Intro:
My application requires getting the external IP address and matching it with an internally acquired address, thus allowing the application to proceed.
For this, I am using a QNetworkAccessManager and QNetworkReply for this purpose.
My code was built using this example as a reference.
What I have tried:
Acquiring an external IP can be done by getting a JSon object from the ipify API.
I confirmed this by:
curl "https://api.ipify.org?format=json"
which in turn responds with my current IP address in the format:
{"ip":"255.255.255.255"}
which is a JSonObject. Using this, I created the code below.
Problem:
The problem is quite simple, I get no response. The
post
request is executed but simply no response (orfinished
) signal is ever triggered.POST
->GET
request
I have changed the code for a
get
request as this solved this no response issue, found on this thread.I did this by specifying the whole url with query parameters in the URL:
QNetworkRequest request(QUrl("https://api.ipify.org?format=json"));
including the header content type and size (as in the example below, finally calling the
QNetworkAccessManager::get()
with:replyExternalAddress = networkManager->get(request);
but this too gave no response.
I figured that it is something small that I am missing, but I simply cannot see it.
Advice?
Code for querying external IP:
// public callable method, starting network request void APICommunicator::requestExternalAddress(){ qInfo(apicommunicator) << "Requesting external IP address from ipify.org"; // creates network request // specifies "format=json" QUrlQuery postData; postData.addQueryItem("format", "json"); QByteArray encodedQuery = postData.toString(QUrl::FullyEncoded).toUtf8(); QNetworkRequest request(QUrl("https://api.ipify.org")); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); request.setHeader(QNetworkRequest::ContentLengthHeader, QString::number(encodedQuery.size())); // creates merged URL from URL and query items and sends a post: // https://api.ipify.org?format=json replyExternalAddress = networkManager->post(request, encodedQuery); // Creates QMetaObject::Connection connection for finished signal from QNetworkReply conExternalAddress = QObject::connect(replyExternalAddress, SIGNAL(finished()), this, SLOT(externalAddressResponse())); // attach error listener to reply addErrorListener(replyExternalAddress, conExternalAddress); } void APICommunicator::externalAddressResponse(){ qDebug(apicommunicator) << "External Address response recieved"; // disconnect signals QObject::disconnect(conExternalAddress); QObject::disconnect(conErrorListener); // read all output from JSon object QByteArray ba = replyExternalAddress->readAll(); // delete QNetworkReply replyExternalAddress->deleteLater(); LogMessageHandler::writeToApiLog(QString("\n\nCALL EXTERNAL [" + replyExternalAddress->request().url().toString() + "]\n" + QString(ba))); QJsonObject doc = QJsonDocument::fromJson(ba).object(); QString ip = doc.value("ip").toString(); QHostAddress address = QHostAddress(); if (ip.isEmpty()) { qWarning(apicommunicator) << "External Address: no data received"; } else { address = QHostAddress(version); } // replies with address to external slot (in main application) emit ExternalAddressReply(address); }
-
@CybeX Hi I made a small Qt test app, called TestExternalAddress which gave me my correct external address, you can try it:
QT += network TARGET = app HEADERS = TestExternalAddress.h SOURCES = main.cpp TestExternalAddress.cpp
main.cpp:
#include <QCoreApplication> #include "TestExternalAddress.h" int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); TestExternalAddress test; return app.exec(); }
TestExternalAddress.h:
#include <QJsonDocument> #include <QJsonObject> #include <QHostAddress> #include <QNetworkReply> class TestExternalAddress : public QObject { Q_OBJECT public: TestExternalAddress(); private slots: void gotReply(QNetworkReply* networkReply); };
TestExternalAddress.cpp:
#include "TestExternalAddress.h" #include "qdebug.h" TestExternalAddress::TestExternalAddress() { QNetworkAccessManager* manager = new QNetworkAccessManager(this); connect(manager,SIGNAL(finished(QNetworkReply*)),SLOT(gotReply(QNetworkReply*))); manager->get(QNetworkRequest(QUrl("https://api.ipify.org?format=json"))); } void TestExternalAddress::gotReply(QNetworkReply* networkReply) { networkReply->deleteLater(); qDebug() << QHostAddress(QJsonDocument::fromJson(networkReply->readAll()).object().value("ip").toString()); }
qDebug() printed out my external ip address :-)