Re: QTcpSocket readyRead strange behavior
You are sending raw bytes and interpreting them on the other end as integers. Don't do that. I told you to encode the size explicitly. If your sender is a 32 bit OS and your receiver a 64 bit OS (or the other way round) your code will fail immediately.
Re: QTcpSocket readyRead strange behavior
you're totally right, but for this example, that's not the point : the code does not fail immediately.
As i am on 2 32bits windows, it works.
(does the size of "short" change between 32 and 64bit OS? i though it could be a problem only if the endianness changed)
Re: QTcpSocket readyRead strange behavior
It is the point because it is this exact variable that is giving you an incorrect result. So first make sure the problem is not there (and not assume it is not there) and then continue elsewhere.
This is sender side compatible with my previous suggestion.
Code:
QByteArray data;
// external byte array containing your data to be sent
quint16 s = data.size();
ba[0] = (s >> 8) & 0xFF;
ba[1] = s & 0xFF;
ba.append(data);
for (i=0;i<vecClient.size();++i)
{
vecClient[i]->write(ba);
}
Re: QTcpSocket readyRead strange behavior
i've got the same problem.
receiver side code :
Code:
void Client::onSocketReadyRead()
{
bufferSocket += pSocket->readAll();
while (bufferSocket.size() >= 2)
{
quint16 size = (bufferSocket.at(0) << 8) + bufferSocket.at(1); // 16bit unsigned value
qDebug()<<"size="<<size;
if (size != 19998)
{
QMessageBox::critical(NULL, tr
("error"), tr
("This is it"));
pSocket->disconnectFromHost();
return;
}
if(bufferSocket.size() <= 2+size) return;
qDebug()<<"data read";
bufferSocket.remove(0,2+size);
}
sender side code:
Code:
void Server::onTimeout()
{
int i;
data.fill(1, 19998);
quint16 s = data.size();
ba[0] = (s >> 8) & 0xFF;
ba[1] = s & 0xFF;
ba.append(data);
for (i=0;i<vecClient.size();++i)
{
vecClient[i]->write(ba);
}
}
Re: QTcpSocket readyRead strange behavior
Dump the data you receive on the receiving end to see whether you are not losing synchronization with your stream.
By the way, if your data is of constant size then why are you sending the size with each bucket?
Re: QTcpSocket readyRead strange behavior
the data is of constant size just for these tests. It will change in the real project :)
I think indeed i've a synchronisation problem. How can it be, as i am in TCP mode?
what do you mean by dump?
should i make a readAll after receiving a full bucket?
Re: QTcpSocket readyRead strange behavior
Quote:
Originally Posted by
naroin
I think indeed i've a synchronisation problem. How can it be, as i am in TCP mode?
If you read less data than you write then you lose synchronisation.
Quote:
what do you mean by dump?
Display on console.
Re: QTcpSocket readyRead strange behavior
that is strange.
logging code:
Code:
quint8 c, c2;
int nCount = 0;
c2 = data.at(0);
for (i=1;i<data.size();++i)
{
++nCount;
c = data.at(i);
if (c != c2)
{
strDebug += tr("%1 * %2 | ").arg(c2).arg(nCount);
c2 = c;
nCount = 0;
}
}
++nCount;
strDebug += tr("%1 * %2 | ").arg(c2).arg(nCount);
qDebug()<<strDebug;
logs:
...
size= 19998
data read
"1 * 19998 | "
size= 19998
size= 19998
size= 19998
data read
"1 * 12494 | 78 * 1 | 30 * 1 | 1 * 7502 | "
i should have only "1" in my data, but i dont have.
78/30 is 4E1E = 19998, that's my size.
it is as if some data were dropped after my 12494 bytes
the server side sends correct data (1* 19998).
Re: QTcpSocket readyRead strange behavior
Quote:
Originally Posted by
naroin
the server side sends correct data (1* 19998).
How do you know that? Do you check the return value of QIODevice::write()? Do you also check the how many bytes are really read on the receiving end?
By the way, get rid of threads, you don't need them and they might be influencing your results somehow.
Re: QTcpSocket readyRead strange behavior
i just changed the receiver side code with windows sockets : it works perfectly.
So
* that's not a sender side problem
* that's not a thread problem
* i think there may be a bug in QTcpSocket::readyRead, but that's very strange as it seems i'm the only guy in the world to have it.
thanks for your help
Re: QTcpSocket readyRead strange behavior
The bug is most likely in the way you use the library. You couldn't have modified your code "in-place", you must have rewritten many aspects of your program changing the way your application works. Somehow strangely thousands of applications work with QTcpSocket without problems and suddenly you believe that there is a bug there because in your application something doesn't work. Think yourself what is more probable.
Re: QTcpSocket readyRead strange behavior
yes that's what i think, but noone here seems to be able to say me what is wrong !
i used the code you sent me, and i got the same problem.
My test applications don't do anything than launching the threads whom i've sent you the code. I really dont understand what can go wrong!
what do you want i send you so you can be able to say me what i did wrong? i really want to know, and you're right, i think it's my fault, but i dont know why.
maybe a problem in the initialization ?
Code:
void Client::run()
{
connect(pSocket, SIGNAL(readyRead()), this, SLOT(onSocketReadyRead()));
pSocket->connectToHost("192.168.50.77", 1234);
if (!pSocket->waitForConnected())
{
qDebug()<<"Unable to connect";
return;
}
exec();
}
Re: QTcpSocket readyRead strange behavior
Note that the slot you call from the thread is not performed inside the thread.
Re: QTcpSocket readyRead strange behavior
how can i do so it is in the thread?
This is one of the things i don't understand well about Qt & threads.
Added after 26 minutes:
i've created a new class ClientInternal, and in my Client code:
Code:
void Client::run()
{
ClientInternal ci;
exec();
}
my ClientInternal code:
Code:
ClientInternal
::ClientInternal(QObject *parent
){
connect(pSocket, SIGNAL(readyRead()), this, SLOT(onSocketReadyRead()));
pSocket->connectToHost("192.168.50.77", 1234);
if (!pSocket->waitForConnected())
{
qDebug()<<"Unable to connect";
return;
}
}
now it seems to work!
why?
Re: QTcpSocket readyRead strange behavior
Because you have the event loop running. Anyway, get rid of the threads, you really don't need them since socket communication is asynchronous.
Re: QTcpSocket readyRead strange behavior
okay but why some data is dropped with my "false thread" ?
is there a event loop for each thread of one for all the application?
Re: QTcpSocket readyRead strange behavior
Each thread can have its own event loop, but it's not automatic, you have to execute it yourself.
Re: QTcpSocket readyRead strange behavior
Quote:
Originally Posted by
naroin
okay but why some data is dropped with my "false thread" ?
is there a event loop for each thread of one for all the application?
Remove threads and all should be working fine. We must have missed the fact you were calling a slot of the QThread object.
Re: QTcpSocket readyRead strange behavior
yes it works well without my QThread object.
But can i have a technical explanation of WHY it didn't work well?
I think i'm missing something important here, and i would like to understand.
However, thanks for your help so far
Re: QTcpSocket readyRead strange behavior
Quote:
Originally Posted by
naroin
But can i have a technical explanation of WHY it didn't work well?
Sure. Your QThread object "lives" in the main thread which means all events for it are processed by the main thread. Your socket lives in the thread controlled by the QThread object. This means the socket gets notified about incoming data by the worker thread and you try to read data from the main thread. Since there is no synchronization between threads here, data may be lost (if you read something and at the same time the other thread writes something to the socket object).