PDA

View Full Version : Blocking QTcpSocket for read/write operations



vcernobai
6th December 2010, 21:49
Hello guys,

I am trying to implement a blocking QTcpSocket for both reading and writing operations. The application to which I am connecting to is written in Java and for very unknown reasons the non-blocking approach doesn't work. With non-blocking approach the highest state reached is QAbstractSocket::ConnectingState and NOT Connected, although the Java client shows it got a new connection.
So this code:


tcpSocket = new QTcpSocket(this);
QObject::connect(tcpSocket, SIGNAL(connected()), SLOT(onConnect()), Qt::DirectConnection);
QObject::connect(tcpSocket, SIGNAL(hostFound()), SLOT(hostFound()), Qt::DirectConnection);
QObject::connect(tcpSocket, SIGNAL(readyRead()), SLOT(readFromSocket()), Qt::DirectConnection);
QObject::connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),
SLOT(displayError(QAbstractSocket::SocketError)), Qt::DirectConnection);

does not work.

By the other side, for the same unkown reasons if I'm using this code:


const int Timeout = 2 * 1000;
if (!tcpSocket->waitForConnected(Timeout)) {
displayError(tcpSocket->error());
}
I enter the QAbstractSocket::ConnectedState ... very strage! Non-blocking approach doesn't work and the blocking on works.

The problem with the blocking approach is that I have to put the code which waits for the data into a separate thread (not to freeze the app), like this:


void EQtClientSocket::run()
{
tcpSocket = new QTcpSocket;

if (!connectionRequested) {
mutex.lock();
cond.wait(&mutex);
mutex.unlock();
}

while(!quit) {

// already connected?
if(tcpSocket->state() == QAbstractSocket::ConnectedState) {
errno = EISCONN;
getWrapper()->error(NO_VALID_ID, ALREADY_CONNECTED.code(), ALREADY_CONNECTED.msg());
}

// starting to connect to server
tcpSocket->abort();
tcpSocket->connectToHost(host, port);

const int Timeout = 2 * 1000;
if (!tcpSocket->waitForConnected(Timeout)) {
displayError(tcpSocket->error());
}
else {
socketState = QAbstractSocket::ConnectedState;
onConnect();
emit connected();
qDebug() << "connection ok";
}

// set client id
while (tcpSocket->bytesAvailable() < (int)sizeof(quint16)) {
if (tcpSocket->waitForReadyRead()) {
onReceive();
qDebug() << "New data available";
}
}

mutex.lock();
cond.wait(&mutex);
mutex.unlock();
}
}

however I need to write something to the socket, which I can't do it from a different thread which created the socket (every QObject should be in the same thread), but I can't write something from the same thread since tcpSocket->waitForReadyRead() would block the thread in most of the time and will wait for the data until it starts again.

I'm stuck. I can't implement a read&write QTcpSocket with the blocking approach.

Please help

squidge
6th December 2010, 22:57
Maybe you have a problem with your event loop? Post a compilable example and maybe we can help.

vcernobai
7th December 2010, 14:37
Maybe you have a problem with your event loop? Post a compilable example and maybe we can help.

Thanks squidge, as per your suggestions I did some more digs and found the problem related to the event loop. This solved the problem.

CPPProger
15th June 2020, 09:43
Please tell me how you solved the problem of starting the event processing cycle (in fact, QCoreApplication::exec()) in Java GUI-app. I have an unsuccessful attempt to start a simple asynchronous socket client - it just does not work in JavaFX. I am trying to make a synchronous client with blocking sockets, but they also require signals and slots and therefore an event loop.