vcernobai
6th December 2010, 20: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
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