OK, also meine ready read sieht bisher wi folgt aus (client / server):
Code: Alles auswählen
void Client::onReadyRead() {
if (tcpSocket == NULL) return;
if (tcpSocket->state() != QAbstractSocket::ConnectedState) return;
QDataStream in(tcpSocket);
in.setVersion(QDataStream::Qt_4_2);
//in.setVersion( in.version() ); // set to the current Qt version instead
if(blockSize == 0) {
if (tcpSocket->bytesAvailable() < (int)sizeof(quint16)) return;
in >> blockSize;
reading_message = true;
}
if(tcpSocket->bytesAvailable() < blockSize) return;
QString msgString;
QVariant msgData;
in >> msgString;
in >> msgData;
emit onMessage(msgString, msgData);
reading_message = false;
blockSize = 0;
if(tcpSocket->bytesAvailable() > 0) onReadyRead();
}
void Client::sendMessage(const QString &msg, const QVariant &data) {
if(tcpSocket == NULL) return;
if(tcpSocket->state() != QAbstractSocket::ConnectedState ) return;
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_2);
//out.setVersion( out.version() ); // set to the current Qt version
//out << (quint32) 0;
out << (quint16) 0;
out << msg;
out << data;
out.device()->seek(0);
// out << (quint32)(block.size() - sizeof(quint32));
out << (quint16)(block.size() - sizeof(quint16));
tcpSocket->write(block);
tcpSocket->flush();
}
void Client::onMessage( const QString &msg, const QVariant &data ) {
if(msg == GD_RETR_WELCOME_STRING) {
if(data.type() == QVariant::Map) {
QMap<QString, QVariant> val;
val = data.toMap();
for(QMap<QString, QVariant>::iterator it = val.begin();
it != val.end(); ++it) {
qDebug() << it.key() << ": " << it.value() << endl;
}
}
readDir(this->_directory);
}
else {
if(data.type() == QVariant::Map) {
QMap<QString, QVariant> val;
val = data.toMap();
for(QMap<QString, QVariant>::iterator it = val.begin();
it != val.end(); ++it) {
qDebug() << it.key() << ": " << it.value() << endl;
}
}
}
}
Sobald etwas empfangen wird, wird dies in der Funktion onMessage() abgearbeitet. Wo soll ich den nun den transfer durchführen.
Den Transfer hätte ich wie folgt gemacht:
Code: Alles auswählen
QFile *file = new QFile;
file->setFileName(filename);
//QFile file(this->qsFilename);
if (!QFile::exists(file->fileName())) {
cerr << QString("The file %1 does not exist.\n").arg(file->fileName()).toStdString() << endl;
cerr << QString("%1").arg(file->errorString()).toStdString() << endl;
cerr << QString("%1").arg(fileError(file->error())).toStdString() << endl;
//return 4;FileFailure;
}
else if (!file->open(QIODevice::ReadOnly)) {
//cerr << QString("Failed to open file %1.\n").arg(file.fileName()).toStdString() << endl;
//cerr << QString("%1").arg(file.errorString()).toStdString() << endl;
cerr << QString("%1: %2").arg(fileError(file->error())).arg(file->errorString()).toStdString() << endl;
//cerr << QString("Failed to open file %1.\n").arg(file.fileName()).toStdString() << endl;
//return FileFailure;
}
QFileInfo *file_info = new QFileInfo(file->fileName());
qint64 file_size = file_info->size();
qint64 bytes_read = 0;
qint64 bytes = BUFFER_SIZE;
qint64 bytes_to_read = bytes;
qint64 max_bytes_to_transfer = TRANSFER_SIZE;
max_bytes_for_all += file_size;
do {
bytes_to_read = ((bytes_read + bytes) >= file_size ? (file_size-bytes_read) : bytes);
char *buffer = new char[bytes_to_read];
memset(buffer, 0, bytes_to_read);
qint64 ret = file->read(buffer, bytes_to_read);
qint64 transfer_byte_count = 0;
while(transfer_byte_count != bytes_to_read) {
qint64 buffer_to_alloc = max_bytes_to_transfer;
if((buffer_to_alloc + transfer_byte_count) > bytes_to_read)
buffer_to_alloc = bytes_to_read - transfer_byte_count;
char *tmp_buffer = new char[buffer_to_alloc];
memset(tmp_buffer, 0, buffer_to_alloc);
memmove(tmp_buffer, buffer + transfer_byte_count, buffer_to_alloc);
QString filename_ = file_info->fileName();
qint64 size = (bytes_read + buffer_to_alloc);
qint64 offset = (bytes_read + transfer_byte_count);
QByteArray bytearray = QByteArray::fromRawData(tmp_buffer, size);
QCryptographicHash crypto_hash(QCryptographicHash::Md5);
crypto_hash.addData(bytearray.constData(), size);
QString md5sum = crypto_hash.result().toHex();
QMap<QString, QVariant> val;
val.insert(GD_FILE_MD5SUM, md5sum);
val.insert(GD_FILE_NAME, filename_);
val.insert(GD_FILE_OFFSET, offset);
val.insert(GD_FILE_SIZE, size);
//val.insert(GD_FILE_DATA, bytearray);
emit sendMessage(GD_MSG_FILE_TRANSFER, val);
/*char *buffer = new char[size];
memset(buffer, 0, size);*/
quint64 bytes_written = 0;
do {
/*quint64 ret = ::recv(tcpSocket->socketDescriptor(), buffer + bytes_read, size - bytes_read, 0);
bytes_read += ret;*/
quint64 ret = tcpSocket->write(tmp_buffer + bytes_written, size - bytes_written);
bytes_written += ret;
} while(bytes_written > size);
delete [] tmp_buffer;
tmp_buffer = NULL;
transfer_byte_count += buffer_to_alloc;
}
delete [] buffer;
buffer = NULL;
bytes_read += bytes_to_read;
/*cout << "Read " << percentage(file_size, bytes_read) << "% from file\r";// << endl;
cout.flush();*/
}while(bytes_read != file_size);
file->close();
delete file_info;
file_info = NULL;
delete file;
file = NULL;
QueryPerformanceCounter(&ende_ticks);
tick_diff = ((double) ende_ticks.QuadPart - (double) start_ticks.QuadPart) / frequenz.QuadPart;
if(i%1000 == 0)
cout << i << "/" << TEST_LOOP << ".) " << "Summary bytes: " << max_bytes_for_all << " in " << tick_diff << " seconds" << endl;
if(i == TEST_LOOP)
break;
}
Das problem ist nur das ich am server nicht tcpSocket->read() aufrufen kann, weil die funktion onReadyRead dauernd dazwischen funkt.
Lg NoRulez
P.S.: die 3 haupt funktionen onReadyRead(), sendMessage(), onMessage() sind auf dem client und server equivalent