Qt-interest Archive, August 2007
Re: QTcpSocket data evaporation issues.
Message 1 in thread
Thomas Richards wrote:
>> Perhaps you could start from the working example and modify it to fit
>> your needs until it doesn't work anymore? That should give a clue. At
>> least we'd have a running example that reproduces the problem.
>>
>
> I've managed to narrow down the problem - The qt docs for the
> waitForReadyRead() method state that:
>
> "If called from within a slot connected to the readyRead() signal,
> readyRead() will not be reemitted."
>
> However, it seems that this is not always the case.. I'm working on some
> example code that reproduces the problem reliably.. will let you know
> more when I figure it out.
>
Hi,
Did you ever solve this problem? I am experiencing a similar problem,
that goes like this: Everything works just fine when sending one and one
message(clarified in the code snippets below), but when one client sends
many messages at once, only the first one gets through. After the first
message has been read, bytesAvailable() will only return 0, even though
I have not read the number of bytes it returned when called before
reading. To make it even more strange; if I deliberately read further
then the first message, I get the rest of the sent messages, so they are
actually in the buffer, but it seems they get lost when
QMessage(clientSocket *) returns. I am using Qt 4.2.3. Each client has
it's own QTcpSocket, and the server has a list of wrapped QTcpSockets.
Code snippets:
/** This is the method in my QTcpSocket-wrapper connected to
* readyRead()-signal.
* I have also wrapped the QTcpServer (in the CoServer2 class), and
* maintain a list of
* clientSocket's in that object. */
void clientSocket::readClient() {
QMessage *l;
CoServer2* server = (CoServer2*)parent();
while (canReadLine()) {
// DEBUG
cout << "Result of bytesAvailable() before read: " <<
bytesAvailable() << endl;
l = new QMessage(this);
l->setFrom(clientId);
// finds the correct receiver client, and uses the
// QMessage::send() function to send the newly
// created QMessage to it.
// (The server only rely the messages.)
server->serve(*l, this);
// DEBUG
cout << "Result of bytesAvailable() after read: " <<
bytesAvailable() << endl << endl;
}
}
/** My own message-format. This constructor does the
* actual reading from the socket, ref. method above.
*/
QMessage::QMessage(QTcpSocket *sPtr) {
QTextStream in(sPtr);
int n = 0;
QMessageTo = 0;
QMessageFrom = 0;
in >> n;
in >> QMessageTo >> QMessageFrom;
content = in.readLine(n);
// DEBUG
cout << "n: " << n << " To: " << QMessageTo << " From: " <<
QMessageFrom << endl;
cout << "Content(received): " << content.toStdString() << endl <<
endl; flush(cout);
}
/**
* Used when sending messages.
* \param m Message
* \param separator Separator
*/
QMessage::QMessage(miMessage m, QString separator) {
QString dta;
content = "";
if (m.data.size()) {
int i;
QTextStream ds(&dta, QIODevice::WriteOnly);
ds << m.data[0].cStr();
for (i = 1; i < m.data.size(); i++)
ds << separator << m.data[i].cStr();
}
QTextStream cs(&content, QIODevice::WriteOnly);
cs << m.to << ' '
<< m.from << ' '
<< m.commondesc.length() << ' '
<< m.common.length() << ' '
<< m.description.length() << ' '
<< m.command.length() << ' '
<< separator.length() << ' '
<< dta.length() << ' '
<< m.commondesc.cStr()
<< m.common.cStr()
<< m.description.cStr()
<< m.command.cStr()
<< separator
<< dta;
QMessageTo = m.to;
QMessageFrom = m.from;
// DEBUG
cout << "To: " << QMessageTo << " From: " << QMessageFrom << endl;
cout << "Content(sent): " << content.toStdString() << endl << endl;
}
/**
* Sends a message on the socket.
*/
void QMessage::send(QTcpSocket* sPtr) {
QTextStream out(sPtr);
out << content.length() << ' ' << QMessageTo << ' ' << QMessageFrom
<< ' ' << content << endl;
out.flush();
}
Anyways; this works fine when sending one message, but when sending
multiple messages bytesAvailable() will first return (e.g.) 10500, but
after one call to QMessage(clientSocket *) in the while-loop in
readClient(), which reads 2600, it will report 0.
_Any_ ideas will be greatly appreciated :)
--
[ signature omitted ]
Message 2 in thread
>
> Hi,
>
Greetings,
> Did you ever solve this problem? I am experiencing a similar problem,
I did, although I don't remember exactly how :(.
However, I do remember encountering some very odd behavior with the data streams I was using. If I remember correctly, you can't change the underlying device when using a QByteArray/QDataStream combination.
Again, I'm not sure how much help this is o you, but It was one of the many stumbling blocks I encountered in my project..
>
> Anyways; this works fine when sending one message, but when sending
> multiple messages bytesAvailable() will first return (e.g.) 10500, but
> after one call to QMessage(clientSocket *) in the while-loop in
> readClient(), which reads 2600, it will report 0.
>
>
Hmm....
> _Any_ ideas will be greatly appreciated :)
>
>
I'll let you know if I remember anything else!
--
[ signature omitted ]