Network send problem
I try to send data over the network, but the server I've programmed doesen't get the data. This code worked befor:
void MainWindow::send()
{
QByteArray qbarr;
QDataStream qdstrm(&qbarr, QIODevice::WriteOnly);
int iCount = qlist->count();
QProgressDialog qprogrsdSend(QString("Sending..."), QString("Cancel"), 0, iCount, this);
qdstrm.setVersion(QDataStream::Qt_4_6);
qprogrsdSend.setWindowModality(Qt::WindowModal);
for(int i = 0; i < iCount; i++)
{
if(qprogrsdSend.wasCanceled())
break;
qdstrm << (quint16)0;
qdstrm << (*qlist)[i].data();
qdstrm.device()->seek(0);
qdstrm << (quint16)(qbarr.size() - sizeof(quint16));
qprogrsdSend.setV开发者_JAVA百科alue(i);
qtcpsoClient->write(qbarr);
qtcpsoClient->flush();
qtcpsoClient->waitForBytesWritten();
qbarr.clear();
}
qlblStatus2->setText("File is send.");
}
But it Takes to many time to send each elemt from qlist. Now I tried to modify the methode, so that first all elements from qlist has been saved in qbarr. And than I send the File. This is the code that doesnt work:
void MainWindow::send()
{
QByteArray qbarr;
QDataStream qdstrm(&qbarr, QIODevice::WriteOnly);
int iCount = qlist->count();
QProgressDialog qprogrsdSend(QString("Sending..."), QString("Cancel"), 0, iCount, this);
qdstrm.setVersion(QDataStream::Qt_4_6);
qprogrsdSend.setWindowModality(Qt::WindowModal);
qdstrm << (quint16)0;
for(int i = 0; i < iCount; i++)
{
if(qprogrsdSend.wasCanceled())
break;
qdstrm << (*qlist)[i].data();
qprogrsdSend.setValue(i);
}
qdstrm.device()->seek(0);
qdstrm << (quint16)(qbarr.size() - sizeof(quint16));
qtcpsoClient->write(qbarr);
qtcpsoClient->flush();
qtcpsoClient->waitForBytesWritten();
qbarr.clear();
qlblStatus2->setText("File is send.");
}
And here is the methode I use to read the data:
void QServerThread::onReadyRead(void)
{
if(read == false)
{
read = true;
emit reading(true);
}
while(!qtcpsoClient->atEnd())
{
QDataStream qdstrmIn(qtcpsoClient);
QDataStream qdstrmOut(qfile);
QByteArray qbarrData;
quint16 qui16BlockSize = 0;
int iVersion = qdstrmIn.version();
qdstrmIn.setVersion(iVersion);
qdstrmOut.setVersion(iVersion);
if(qtcpsoClient->bytesAvailable() < (int)sizeof(quint16))
break;
qdstrmIn >> qui16BlockSize;
if(qtcpsoClient->bytesAvailable() < qui16BlockSize)
break;
qdstrmIn >> qbarrData;
qdstrmOut << qbarrData.data();
qfile->flush();
}
read = false;
emit reading(false);
}
I hope somebody can help me. Thanks
Paul
Couldn't the problem be in your server? I suppose you connect your onReadyRead to readyRead singal of the socket. That signal is emitted once per a chunk of data received. So if you send all your data at once, it is possible the signal gets emitted only once. I suppose qtcpsoClient
is the socket. Now, I can see this happening:
You ask bytesAvailable() < somesize
before that much data arrived yet. In that case you read a size, but break out right after that and on next read you already lost your size information and read garbage.
This might not be a problem before as you send multiple short messages, and every message managed to fully arrive before you asked for the data size. The bug was still there though.
On a sidenote. In your original client code - why did you flush()
and waitForBytesWritten()
after every write
? This may be the reason why it was so slow.
[edit: corrected based on Sergey Tachenov's comment]
精彩评论