QTcpSokcet connected() signal not fired
-
I'm working on a project with Qt on windows. I connected the QTcpSocket's connected() signal to a slot, but after call "connectToHost', my slot won't called, so I doubt the 'connected()' signal is not fired or delayed.
proc() { .... connect(_socket, SIGNAL(connected()), this, SLOT(socket_connected()), Qt::DirectConnection); _socket->connectToHost(tester->ip_info().ip_addr.toString(), TCP_COMM_PORT, QTcpSocket::ReadWrite, QTcpSocket::IPv4Protocol); ... }
Anyone can give a help? Where my code is wrong?
Best reards.
-
@diverger You should connect http://doc.qt.io/qt-5/qabstractsocket.html#error-1 signal to a slot and print the error there to check whether any error occurs. And you should check whether the connection for connected actually succeeded:
qDebug() << connect(_socket, SIGNAL(connected()), this, SLOT(socket_connected()), Qt::DirectConnection);
should output true.
-
@jsulm Thanks for the help. It return true. Is it mandatory to call
_socket->waitForConnected(timeout);
after 'connecToHost()' ? I find if I add the clause above, my slot is called. IMHO, 'waitForxxxxx' are for blocking operations, why it will affect the async-signals?
Now, i'm a little confused about how to use the APIs Qt provided for sockets.
-
@jsulm I create a worker class and move it to a new thread. In the worker class's constructor, I connect the socket signals to the slots in the same class.
connect(_socket, SIGNAL(connected()), this, SLOT(socket_connected())); connect(_socket, &QTcpSocket::readyRead, this, &XXXXX::read_ready); connect(_socket, &QTcpSocket::bytesWritten, this, &XXXXX::bytes_written);
And the main worker code is:
void XXXXX::proc_start() { CommProc::proc_start(); while (this->_is_enabled) { qDebug() << QThread::currentThreadId(); eth_comm_command_pkt_t command_pkt = { MODEL_GUID, 0, 0 }; eth_comm_status_pkt_t status_pkt; auto timeout = 5 * 1000; _socket_connected = false; _socket->connectToHost(tester->ip_info().ip_addr.toString(), TCP_COMM_PORT, QTcpSocket::ReadWrite, QTcpSocket::IPv4Protocol); if (!_socket->waitForConnected(timeout)) { // error emit socket_error(_socket->error(), _socket->errorString()); return; } while (!_socket_connected); // send command _socket_bytes_written = 0; command_pkt.command = 1; qint64 bytes_written = _socket->write((char const *)&command_pkt, sizeof(command_pkt)); if (bytes_written < 0) { // error emit socket_error(_socket->error(), _socket->errorString()); return; } while (!_socket->waitForBytesWritten(timeout)) { emit socket_error(_socket->error(), _socket->errorString()); } while (_socket_bytes_written < sizeof(command_pkt)) { } // read status if (!_socket->waitForReadyRead(timeout)) { emit socket_error(_socket->error(), _socket->errorString()); return; } while (_socket_bytes_ready < sizeof(status_pkt)) { } _socket->read((char *)&status_pkt, sizeof(status_pkt)); if (status_pkt.status == status_pkt.STA_OK) { // qDebug() << "Send command done"; } else { qDebug() << "Command error!"; } } }
I've debuged it, the worker code indeed run in a new thread.
-
@diverger You should remove all that while loops, because they block the event loop. Blocked event loop means: no signals can be emited/handled. I would suggest to take a look at Qt networking examples to see how Qt networking should be used. It is asynchronous event driven.