I know some similar questions may have been asked already, but the answers to those I found covered very specific problems and I still haven't figured it out.
In my program I'm creating a QObject (called QPeer) that uses a QTcpSocket to communicate with another such object over a network. QPeer has a slot that accepts a QByteArray with data (sendData(QByteArray)
). The entire contents of that array are considered to be one 'message' and they are written to the socket. I want to do the following: every time a message is written, I want the receiving QPeer to emit its signal dataReceived(QByteArray)
exactly once, that QByteArray containing the entire message. (NOTE: all signals/slots, both private ones connecting the QPeer with its socket and the public ones such as sendData(QByteArray)
are serialized by using Qt::QueuedConnection
whenever necessary.)
I use the signal QTcpSocket::readyRead()
for asynchronous reading from the socket. Now I know I can't just call QTcpSocket::write()
once in sendData and then assume that for every write I do, the QTcpSocket on the other side produces exactly one readyRead signal. So what should I do?
This is my idea, please tell me if this will work:
WRITING:
void QPeer::sendData(QByteArray data)
{
// TODO: write data.size() as raw int of exactly 4 bytes to socket
const char *bytes = data.constData();
int bytesWritten = 0;
while (bytesWritten < data.size())
bytesWritten += _socket->write(bytes + bytesWritten);
}
READING:
now I want the read function (connected to QTcpSocket::readyRead()
) to use the header (the 4 byte int specifying the length of the message) and then read that amount of bytes; next emit dataReceived with exactly those bytes. I'm having serious trouble trying to do this. For example: what to do if readyRead is emitted and I can read the header of a message, but not the amount of bytes specified? Or what if a header has only been received partially?
1. How do I correctly write the header (4 byte int) to the socket?
2. How do I correctly implement the read function so that it does what I want?
Any tips are welcome. Thanks!