ich versuche ein Programm für den FileTransfer zu basteln.
Folgender Code-Teil sendet eine Datei (befindet sich in der run()-Methode eines Threads):
Code: Alles auswählen
QTcpSocket socket;
socket.connectToHost(host,port);
socket.waitForConnected();
QFile f(file);
f.open(QIODevice::ReadWrite);
qint64 size = f.size();
qint64 current = 0;
qint64 read;
char data[65536];
while (!f.atEnd() && socket.state() == QTcpSocket::ConnectedState)
{
read = f.read(data,65536);
socket.write(data,read);
socket.flush();
socket.waitForBytesWritten();
current += read;
emit progress(current,size);
}
f.close();
Die Datei wird von einem QTcpServer empfangen (ohne Threads). Im Prinzip habe ich das Signal newConnection() mit einer Methode verbunden, welche eine Datei QFile f; bereitstellt und den dazugehörigen Socket mit dem Signal ReadyRead() verknüpft, sodass bei eingehenden Bytes folgende Methode aufgerufen wird:
Code: Alles auswählen
void recvServer::onRead()
{
QByteArray data = conn->read(qMin(this->bytesLeft, (quint64)65536));
f.write(data);
f.flush();
this->bytesLeft -= data.length();
if (this->bytesLeft == 0)
{
f.close();
fin = true;
conn->disconnectFromHost();
emit finished();
}
emit progress(size-bytesLeft,size);
}
Fazit: kleine Dateien werden korrekt übertragen. Große Dateien (1.8 GB) werden manchmal unvollständig übertragen, der Abbruch erfolgt nicht-deterministisch aber meistens irgendwo zwischen 30 und 40 MB (mit Ausnahmen). Die beiden Dateien stimmen bis zur Bruchstelle bitweise überein. Den Debugmeldungen und dem Fortschrittsbalken ist zu entnehmen, dass die Datei von Clientseite vollständig gesendet wird. Beim Server kommt hingegen nur die unvollständige Datei an. Außerdem geht der Fortschrittsbalken beim Senden viel schneller als beim Empfangen. Und der GUI hängt beim Empfänger.
Meine Vermutung: Das mit dem ReadyRead-Signal ist dem Empfänger zu aufwendig und er liest zu langsam. Ich habe die Befürchtung, dass ich den Empfänger in ein Thread verpacken muss (was ich aber nicht wirklich will -.-)
LG und danke schon im Voraus
Nachtrag: ich teste die gesamte Konstruktion auf einem einzigen Rechner mit der Loopback-Adresse unter Ubuntu Linux. Außerdem ist ein QTcpServer für nur eine Datei bestimmt. Es gibt also nicht das Problem, dass auf einen Server mehrfach zugegriffen werden könnte.