QTcpSocket doesn't work as expected (Qt5.5.1, win10)
-
I'm using this simple echo server in python: http://ilab.cs.byu.edu/python/socket/echoserver.html
It works with the client in python but I can't get it to wotk with my client written in Qt/C++.
They successfully establish connection bu there is no data being sent between them.
I was able to make my client sent data (for some reason it required forcibly flushing socket after every write) but it still doesn't receive any messages from server. No readyRead() is being fired and bytesAvailable is 0.#include <QDataStream> #include <QTextStream> #include <QDebug> #include "echoclient.h" EchoClient::EchoClient(QObject *parent) : QObject(parent), serverSocket(new QTcpSocket(this)), networkSession(nullptr) { connect(serverSocket, &QTcpSocket::readyRead, this, &printEcho); connect(serverSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError))); connect(serverSocket, &QTcpSocket::connected, this, [this](){QTextStream(stdout) << "Connection established" << endl; messageLoop();}); connect(serverSocket, QTcpSocket::disconnected, this, &disconnect); } void EchoClient::connectToServer() { serverSocket->connectToHost(serverIP, serverPort); } void EchoClient::setIP(const QString &ip) { serverIP = ip; } void EchoClient::setPort(quint16 port) { serverPort = port; } void EchoClient::sendMessage(const QString &msg) { qDebug() << serverSocket->write(msg.toUtf8()); qDebug() << serverSocket->isOpen(); // true qDebug() << serverSocket->flush(); // true, why do I need it? It should be working without it qDebug() << "bytes available: " << serverSocket->bytesAvailable(); } void EchoClient::disconnect() { QTextStream(stdout) << "Disconnected" << endl; } void EchoClient::printEcho() const { QDataStream in(serverSocket); in.setVersion(QDataStream::Qt_5_5); QString echoMsg; in >> echoMsg; QTextStream(stdout) << "Echo: " << echoMsg << endl; } void EchoClient::displayError(QAbstractSocket::SocketError) const { qDebug("error occured"); } void EchoClient::messageLoop() { QTextStream(stdout) << "You can enter messages now" << endl; QTextStream conin(stdin); while (true) { QString msg; conin >> msg; sendMessage(msg); } }
If I add waitForReadyRead() in the messageLoop() it starts receiving something though. Why?
-
QTcpSocket requires the Qt event loop to be running unless you use the wait...() member functions for all operations. You are using a blocking call to read from the console, if you want everything to use the Qt event loop you must use QCoreApplication and either QSocketNotifier or QFile to access stdin within the event loop.
-
QTcpSocket requires the Qt event loop to be running unless you use the wait...() member functions for all operations. You are using a blocking call to read from the console, if you want everything to use the Qt event loop you must use QCoreApplication and either QSocketNotifier or QFile to access stdin within the event loop.
@bsomervi I'm creating default Qt console application so it should already contain eventloop. My main is:
#include <QCoreApplication> #include <QTextStream> #include "echoclient.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QTextStream conout(stdout); QTextStream conin(stdin); EchoClient echocl; conout << "Enter IP: " << endl; QString ip; conin >> ip; echocl.setIP(ip); conout << "Enter port: " << endl; quint16 port; conin >> port; echocl.setPort(port); echocl.connectToServer(); return a.exec(); }
Also, as I mentioned - connection to server is working fine (I get notification by signal).
-
Your slot that handles the TCP/IP connection never exits, it has a while(true) ; loop therefore the event loop is stalled. You need to either handle the console I/O using events as I suggest or use the wait...() QTcpSocket member functions and not have an event loop.
-
Thanks. I just got rid of the loop and instead called that method after I receive any data.
P.S. Don't know how to properly mark this question solved with the new layout.