QByteArray per TcpSocket verschicken
-
PeterLustig
- Beiträge: 386
- Registriert: 21. November 2007 20:07
ich poste euch hier mal meinen "Client"-Code. Ser Servercode sieht dementsprechend quasi identisch aus was senden und empfangen betrifft...mein Problem ist nach wie vor, dass nicht alles ankommt was ich sende.
Viele Grüße, Viper2000
Viele Grüße, Viper2000
Code: Alles auswählen
#include "RF_Network_Server_ClientThread.h"
#include <QtNetwork>
RF_Network_Server_ClientThread::RF_Network_Server_ClientThread(int socketDescriptor, QObject *parent)
: QThread(parent), socketDescriptor(socketDescriptor)
{
connect(&gTcpSocket, SIGNAL(readyRead()),
this, SLOT(readData()));
connect(&gTcpSocket, SIGNAL(disconnected()),
this, SLOT(disconnect()));
connect(this, SIGNAL(finished()),
this, SLOT(deleteLater()));
if (!gTcpSocket.setSocketDescriptor(socketDescriptor))
{
///emit error(gTcpSocket.error()); //TODO
return;
}
qDebug("***ClientThread constructed***");
qDebug() << "Client Address: " << gTcpSocket.peerAddress().toString();
}
void RF_Network_Server_ClientThread::disconnect()
{
gTcpSocket.disconnectFromHost();
if (gTcpSocket.state() == QAbstractSocket::UnconnectedState || gTcpSocket.waitForDisconnected())
qDebug("Client Disconnected");
//Teilt der Thread-Ereignisschleife das Ende des Threads mit
this->exit();
}
void RF_Network_Server_ClientThread::run()
{
//In Ereignisschleife eintreten
if (this->exec() == 0)
qDebug() << "Thread Regulaer beendet";
}
void RF_Network_Server_ClientThread::readData()
{
gBlockSize = 0;
gReceivedData.clear();
QDataStream in(&gTcpSocket);
in.setVersion(QDataStream::Qt_4_3);
if (gBlockSize == 0)
{
if(gTcpSocket.bytesAvailable() < (int)sizeof(quint32))
return;
in >> gBlockSize;
}
if (gTcpSocket.bytesAvailable() < gBlockSize)
return;
in >> gReceivedData;
qDebug() << "Received size of Data from Client: " << gBlockSize;
emit dataReceived(unCompressData(gReceivedData));
}
bool RF_Network_Server_ClientThread::sendData(QDomDocument& iData)
{
QByteArray mBlock;
QByteArray mTempArray;
mTempArray = compressData(iData);
QDataStream mOut(&mBlock, QIODevice::WriteOnly);
mOut.setVersion(QDataStream::Qt_4_3);
mOut << (quint32)mTempArray.size();
mOut << mTempArray;
qint64 mWritten = gTcpSocket.write(mBlock);
gTcpSocket.flush();
//msleep(60); //TODO: Pause- Größe Ermitteln
if (mWritten == mBlock.size())
{
qDebug("Alle Bytes erfolgreich geschrieben");
return true;
}
else if (mWritten == -1) //write returns -1 if an error occurs
{
qDebug() << "Ein Fehler wurde von write gemeldet: " << gTcpSocket.errorString();
return false;
}
else
{
qDebug("Unbekannter Fehler beim Senden");
return false;
}
}
QDomDocument RF_Network_Server_ClientThread::unCompressData(QByteArray& iArray)
{
QDomDocument mUncompressedData;
QString mParseError;
if (!mUncompressedData.setContent(qUncompress(iArray), &mParseError))
qDebug() << "XML Parse not successful - Error: " << mParseError;
else
qDebug() << "XML Parse successful";
return mUncompressedData;
}
QByteArray RF_Network_Server_ClientThread::compressData(QDomDocument& iXML)
{
QByteArray mCompressedData;
mCompressedData = qCompress(iXML.toByteArray());
return mCompressedData;
}
RF_Network_Server_ClientThread::~RF_Network_Server_ClientThread()
{
qDebug("***ClientThread destructed***");
}
Ich bin nicht die Signatur, ich putz hier nur 
Hi viper,
füge mal den code am Ende von readData() ein
vielleicht bekommst Du eine Idee worüber Sephral und ich in den vorhergehenden Posts diskutiert haben.
füge mal den code am Ende von readData() ein
Code: Alles auswählen
void RF_Network_Server_ClientThread::readData()
{
...
qDebug() << gTcpSocket.bytesAvailable();
}@Maxima&Sephral&PeterLustig&Andere: Hier mal ein Auszug vom Output meines Programmes mit deinem qDebug...
Habe 1000 QDomDocuments der gleichen Größe in ner schleife versendet. Bis zum 879ten Dokument war bytesAvailable auf 0. Dann habe ich aus Spass mal den Firefox angeworfen. Und sobald ich den Firefox gestartet hatte ging die Ausgabe von bytesAvailable hoch wie ne Rakete
Also habe ich jetzt daraus geschlossen, dass solange die CPU nur mit dem lesen vom Netzwerk beschäftigt ist und noch etwas Luft hat, es keine Fehlenden Daten gibt. Ist die CPU jedoch mit was anderem beschäftigt, so bekomme ich etliche Fehlende Daten auf Empfängerseite. Bei diesem Durchlauf war übrigens bei 888 empfangenen Dokumenten von 1000 gesendeten Dokumenten Schluss.
Hoffe ihr könnt mir noch weitere Tips geben wie ich dieses fatale Verhalten beseitigen kann. Gruß, Viper
Habe 1000 QDomDocuments der gleichen Größe in ner schleife versendet. Bis zum 879ten Dokument war bytesAvailable auf 0. Dann habe ich aus Spass mal den Firefox angeworfen. Und sobald ich den Firefox gestartet hatte ging die Ausgabe von bytesAvailable hoch wie ne Rakete
Hoffe ihr könnt mir noch weitere Tips geben wie ich dieses fatale Verhalten beseitigen kann. Gruß, Viper
Code: Alles auswählen
.
.
.
.
Empfangen: 879
21896 <<--- Dies ist die Rückgabe von QTcpSocket::bytesAvailable()
Empfangen: 880
21896
Empfangen: 881
21896
Empfangen: 882
21896
Empfangen: 883
21896
Empfangen: 884
21896
Empfangen: 885
21896
Empfangen: 886
22134
Empfangen: 887
22134
Empfangen: 888
Ich bin nicht die Signatur, ich putz hier nur 
Hi Viper,
die Lösung Deines Problems wurde hier in diesem Thread schon mehrfach beschrieben.
Dir gehen keine Daten verloren, die Daten versauern lediglich in Deinem Empfangs-Buffer
Bau Deine Empfänger-Routine so um, dass du auf einmal auch mehrere QByteArrays verarbeiten kannst bis der Buffer leer ist.
Du darfst Dich nicht darauf verlassen, dass du immer ein readyRead-Signal bekommst für jedes einzelne empfangene QByteArray.
Ciao,
Sephral
die Lösung Deines Problems wurde hier in diesem Thread schon mehrfach beschrieben.
Dir gehen keine Daten verloren, die Daten versauern lediglich in Deinem Empfangs-Buffer
Bau Deine Empfänger-Routine so um, dass du auf einmal auch mehrere QByteArrays verarbeiten kannst bis der Buffer leer ist.
Du darfst Dich nicht darauf verlassen, dass du immer ein readyRead-Signal bekommst für jedes einzelne empfangene QByteArray.
Ciao,
Sephral
ok - Danke Euch, ich werde es versuchen und Berichten. Jetzt ist mir zumindest das Problem erstmal richtig klar geworden
War bisher immer der Meinung, dass immer wenn das readyRead() Signal kommt etwas zum lesen vorhanden ist. Und wenn ich dann das weggelesen habe wieder ein readyRead() Signal kommt. Jetzt ist mir klar, dass bei nem readyRead() Signal auch mehr als ein ByteArray angekommen sein kann 
Naja aus Fehlern lernt man eben doch dazu.
Naja aus Fehlern lernt man eben doch dazu.
Ich bin nicht die Signatur, ich putz hier nur 
Ich habe das Problem nun Erfolgreich gelöst!
Meine Empfangsroutine:
diese Routine arbeitet sauber den Puffer ab solange bis er leer ist. Wenn er leer ist wird erneut das Signal readyRead vom Socket emittiert und meine Empfangsroutine beginnt von erneut durchzurattern.
Das nur mal als kurze Rückmeldung für den Thread...könnte also als "gelöst" gekennzeichnet werden
Meine Empfangsroutine:
Code: Alles auswählen
void RF_Network_Client_CommunicationThread::readData()
{
//Socket an den Datenstrom binden
QDataStream in(&mTcpSocket);
in.setVersion(QDataStream::Qt_4_3);
while (mTcpSocket.bytesAvailable() >= (int)sizeof(quint32))
{
if (mBlockSize == 0)
{
in >> mBlockSize;
//qDebug() << "BlockSize: " << mBlockSize;
//qDebug() << "BufferSize: " << mTcpSocket.bytesAvailable();
}
//Warten bis alle Nutzdaten im internen Socketpuffer angekommen sind.
if (mTcpSocket.bytesAvailable() < mBlockSize)
{
//qDebug() << "Return reached";
return;
}
//Nutzdaten aus dem Datenstrom lesen
in >> mReceivedData;
emit dataReceived(mReceivedData);
mBlockSize = 0;
mReceivedData.clear();
}
}
Das nur mal als kurze Rückmeldung für den Thread...könnte also als "gelöst" gekennzeichnet werden
Ich bin nicht die Signatur, ich putz hier nur 