Unsolved Cannot get host address from name
-
Hi,
I'm new to Qt. I'm trying to make a very simple console application using Qt Network.
In this application, I want to get the host IP from its address.
I want to get this IP in a blocking way : I am not interested in callbacks and asynchronous.But both ways, asynchronous QHostInfo::lookupHost(); and synchronous QHostInfo::fromName();, fail to me. I do not understand why and I would need at least one of them to work.
Here is the code :
const QString serverName = "lobby.faforever.com"; QHostAddress serverAddress; quint16 serverPort = 8001; QTcpSocket *socket = nullptr; class Task : public QObject { public: void resolveDNS(QString DNS, QHostAddress& address) { QHostInfo::lookupHost(DNS, this, SLOT(finished(address, QHostInfo))); }; void finished(QHostAddress& address, QHostInfo hostInfo){ address = hostInfo.addresses()[0]; } }; int main() { qDebug() << "Program started" << endl; qStdOut() << "->RESOLVING ADDRESS FOR " << serverName.toUtf8() << endl; // NON-BLOCKING WAY : // // Task thisTask; // thisTask.resolveDNS(serverName, serverAddress); // while (serverAddress.isNull()){ // //do nothing // } // // BLOCKING WAY : // // QHostInfo servInf = QHostInfo::fromName(serverName); // serverAddress = servInf.addresses()[0]; // qStdOut() << "->CONNECTING TO " << serverAddress.toString() << ":" << serverPort << endl; socket->connectToHost(serverAddress, serverPort); socket->setSocketOption(QTcpSocket::KeepAliveOption, 1); // we need to wait... if(socket->waitForConnected(1000)) { qDebug() << "Connected!"; } return 0; }
The blocking way, "fromName", is returning this upon fire :
QObject::connect: Cannot connect (null)::destroyed() to QHostInfoLookupManager::waitForThreadPoolDone()
The non-blocking way, via my resolveDNS() function, returns this :
QHostInfo::lookupHost() called with no event dispatcher
What can I do ?
Regards, -
Have you seen? http://doc.qt.io/qt-5/qdnslookup.html
I'm sorry I don't have the effort to understand, to me it looks like you are not properly using / trying to abuse signals and slots - or something. I'd just use them in the conventional way.
I myself would use a connection using the new syntax like:
connect(dns, QDnsLookup::finished, this, &MyObject::handleServers);
-
@rackover This simply cannot work as you dont't have QApplication instance and you do not start event loop. Please take a look at Qt basics and examples.
Don't do such things in event driven applications like Qt application! You block the event loop!
while (serverAddress.isNull()){ do nothing }
-
@rackover
Your socket is allways null. Where is a socket = new QTcpSocket() ??
Also@rackover said in Cannot get host address from name:
class Task : public QObject
{
public:Signals and slots are available only in QObject derived classes, and a Q_OBJECT macro is needed. You forget Q_OBJECT.
Correct Isclass Task : public QObject { Q_OBJECT public:
Also your finished function does not a slot:
correct is :public slots: void finished(QHostAddress& address, QHostInfo hostInfo){ address = hostInfo.addresses()[0]; }
Use this example to solve your problem:
void MainWindow::lookUp(QHostInfo info) { if (info.error() != QHostInfo::NoError) { qDebug() << info.errorString(); return; } for (int i = 0; i < info.addresses().size(); i++) { qDebug() << info.addresses().at(i).toString(); } } void MainWindow::on_pushButton_clicked() //on_pushButton_clicked() is a your void resolveDNS(QString DNS, QHostAddress& address) { QHostInfo::lookupHost("qt.io", this, SLOT(lookUp(QHostInfo))); }
private slots: void lookUp(QHostInfo info);
-
Thank you for all your answers.
Given the small app I want to build, the blocking synchronous way is what I need to make work.
So I've enhanced my code a bit and deleted the other :
//#include <QCoreApplication> #include <QtCore> #include <QtNetwork> //Debugging #include <QDebug> using namespace std; const QString serverName = "lobby.faforever.com"; QHostAddress serverAddress; quint16 serverPort = 8001; string firstQuery = "{'command':'ask_session','version':'1.0','user_agent':'faf-client'}"; QTcpSocket *socket = new QTcpSocket(); QTextStream& qStdOut() { static QTextStream ts( stdout ); return ts; } int main() { qDebug() << "Program started" << endl; qStdOut() << "->RESOLVING ADDRESS FOR " << serverName.toUtf8() << endl; // BLOCKING WAY : // QHostInfo servInf = QHostInfo::fromName(serverName); QList<QHostAddress> addressesList = servInf.addresses(); for (int i = 0; i < addressesList.size(); ++i) { if (addressesList.at(i) != QHostAddress::LocalHost && addressesList.at(i).toIPv4Address() ) { serverAddress = addressesList.at(i); break; } } // qStdOut() << "->CONNECTING TO " << serverAddress.toString() << ":" << serverPort << endl; socket->connectToHost(serverAddress, serverPort); socket->setSocketOption(QTcpSocket::KeepAliveOption, 1); // we need to wait... if(socket->waitForConnected(1000)) { qDebug() << "Connected!"; } return 0; }
Adding " new QTcpSocket();" instead of starting the socket as a null value makes the thing work. But despite it working, the same error is still displaying :
->RESOLVING ADDRESS FOR lobby.faforever.com QObject::connect: Cannot connect (null)::destroyed() to QHostInfoLookupManager::waitForThreadPoolDone() ->CONNECTING TO 148.251.238.131:8001 Connected!
Why that ?
You said the socket should be up before doing a host lookup : but how can my socket be connected to Host if I dont know host address first ? -
@rackover said in Cannot get host address from name:
but how can my socket be connected to Host if I dont know host address first ?
Using the URL?
http://doc.qt.io/qt-5/qabstractsocket.html#connectToHost -
This post is deleted! -
@rackover The host name is the URL: "lobby.faforever.com"...
-
Using the servername directly, i'm still getting the same error.
QObject::connect: Cannot connect (null)::destroyed() to QHostInfoLookupManager::waitForThreadPoolDone()
Why that ?