PDA

View Full Version : QTCPSocket readyRead() signal not emitting signal always



Vagesh
2nd January 2015, 13:19
I have created new thread and created object of QTCPSocet.

{
m_pSocket=new QTcpSocket();
m_pSocket->connectToHost(m_sIPAdress,m_nPort);
connect(m_pSocket,SIGNAL(readyRead()),this,SLOT(So cketDataReceived()),Qt::QueuedConnection);

}

Server Sends data in UTF8 format.

m_qstrNextMesssage is QString

void SocketReader::SocketDataReceived()
{
while (m_pSocket->bytesAvailable())
{
m_qstrNextMesssage.append(m_pSocket->readAll());

emit DataReceived(m_qstrNextMesssage);
}
m_qstrNextMesssage.clear();
}

}



If my server sends the data within 1 sec then I am not getting the readyRead() signal.

I saw that this issue has been faced by many people.

But still I am facing the issue.

!!! Can you guys please help me !!!

wysota
2nd January 2015, 13:28
What is "this"? Does the thread owning "this" run the event loop?

Vagesh
2nd January 2015, 13:34
Hi wysota,

Yes the thread is owning this event loop

wysota
2nd January 2015, 14:11
And which thread is that? What is the class of "this"? What is the relation of SocketReader and the thread object running it?

Vagesh
2nd January 2015, 14:18
What I did is
I created object of (actual it is doing both reading and writing name changed for Simplicity) SocketReader (pSocketReader) and new QThread object (pSocketThread)
and then done pSocketReader ->moveToThread(pSocketThread);

attached thread signal
connect(pSocketThread,SIGNAL(started()),pSocketRea der,SLOT(Initialize()));

In Initialize() written following code.
{
m_pSocket=new QTcpSocket();
m_pSocket->connectToHost(m_sIPAdress,m_nPort);
connect(m_pSocket,SIGNAL(readyRead()),this,SLOT(So cketDataReceived()),Qt::QueuedConnection);
}


and in
void SocketDataReceived ()
{
while (m_pSocket->bytesAvailable())
{
m_qstrNextMesssage.append(m_pSocket->readAll());

emit DataReceived(m_qstrNextMesssage);
}
m_qstrNextMesssage.clear();
}


Also I would like to know the signal is lost means data is also lost. Is there any wait to get data. My main problem is data getting lost.

anda_skoa
2nd January 2015, 14:53
Data is not getting lost even if you do not process a readyRead() signal. QTcpSocket has an internal buffer and stores received data until you read it.
For TCP that is actually even true on the operating system level.

A couple of things that are weird:
- why do you connect to the readyRead() signal using a Qt::QueuedConnection?
- why do you not connect after socket creation but after calling connectToHost()?

Cheers,
_

Vagesh
2nd January 2015, 15:05
Hi Anda_skoa,

That's what my understanding is regarding TCP. But then in that case why the messages are getting lost. Ideally whenever next readyRead signal raised I should receive previous messages right?

Is there something like append data.

Regarding QueuedConnection. As this is in same thread signals will be send directly. To avoid message loss I thought If i make it queued then message wil not get lost atleast they will be queued. But it does not help.

Regarding connect after calling connectToHost() I changed the sequence but it dose not helped

wysota
2nd January 2015, 15:57
In TCP data does not come in "messages". readyRead() is emitted whenever new data comes in. The number of readyRead() signals you receive doesn't matter, there is no data "attached" to it, at any moment in time calling readAll() on the socket will read all pending data. At the same time your data processing loop is probably invalid. I don't know what is the nature of your data but you should be prepared that it comes in multiple chunks (e.g. one octet each) so you should detect record boundaries yourself. Unless the receiver of your DataReceived() signal does that, you should do that before emitting the signal.

anda_skoa
2nd January 2015, 16:16
That's what my understanding is regarding TCP. But then in that case why the messages are getting lost.

Unless you read and then discard data it cannot get lost.



Ideally whenever next readyRead signal raised I should receive previous messages right?

readyRead() is emitted whenever new data becomes available.
How much data depends on a lot of factors. See wysota's comment.



Is there something like append data.

You are already using it. It is, unsurprisingly, called append().



Regarding QueuedConnection. As this is in same thread signals will be send directly. To avoid message loss I thought If i make it queued then message wil not get lost atleast they will be queued. But it does not help.

A signal is never "lost".
Your QueuedConnection just makes the slot call delayed by another trip through the event queue.
That, of course, is your choice. Just doesn't strike me as particular useful in this case. Usually one wants to process network events right away.

Cheers,
_

Vagesh
3rd January 2015, 12:11
Hi Wysota,

Thanks a lot for reply.

I am getting XML UTF8 based data from sender/server. I can not control sender or can not modify. But sender always sends a complete XML message at one time.
I observed that if a sender sends 3 XML around of length 80-100 character) then atlist 1 complete XML message is getting lost.

Whenever I got a signal I am just reading the data and emitting signal to main thread so that it can actually process the messages.

Do you see any issue in my code.

wysota
3rd January 2015, 12:25
But sender always sends a complete XML message at one time.
The application is sending an XML message at one time, the TCP/IP stack is not. That's the whole point of our conversation -- one "send" does not equal to one "receive".

Do you see any issue in my code.
Yes, you ignore the fact that TCP is a stream protocol and not a datagram protocol. If you want to handle XML messages then you have to detect the start and end of a message by yourself. QXmlStreamReader can help you with that a bit.