// Richiesta connessione TCP in ingresso void DuktoProtocol::newIncomingConnection() { // Verifica presenza connessione pendente if (!mTcpServer->hasPendingConnections()) return; // Recupero connessione QTcpSocket *s = mTcpServer->nextPendingConnection(); // Se sto già ricevendo o inviando, rifiuto la connessione if (mIsReceiving || mIsSending) { s->close(); return; } // Aggiornamento interfaccia grafica receiveFileStart(s->peerAddress().toString()); // Impostazione socket TCP corrente mCurrentSocket = s; // Attesa header della connessione (timeout 10 sec) if (!s->waitForReadyRead(10000)) { // Non ho ricevuto l'header della connessione, chiudo mCurrentSocket->close(); delete mCurrentSocket; mCurrentSocket = NULL; return; } // Registrazione gestori eventi socket connect(mCurrentSocket, SIGNAL(readyRead()), this, SLOT(readNewData()), Qt::DirectConnection); connect(mCurrentSocket, SIGNAL(disconnected()), this, SLOT(closedConnectionTmp()), Qt::QueuedConnection); // Inizializzazione variabili mIsReceiving = true; mTotalReceivedData = 0; mElementSize = -1; mReceivedFiles = new QStringList(); mRootFolderName = ""; mRootFolderRenamed = ""; mReceivingText = false; mRecvStatus = FILENAME; // -- Lettura header generale -- // Numero entità da ricevere mCurrentSocket->read((char*) &mElementsToReceiveCount, sizeof(qint64)); // Dimensione totale mCurrentSocket->read((char*) &mTotalSize, sizeof(qint64)); // Inizio lettura dati sui file readNewData(); }
void DataLoader::on_timeout() { if (canceling) { deleteLater(); return; // we leave with guiUpdateTimer not active } parsing = true; // process could exit while we are processing so save the flag now bool lastBuffer = isProcExited; loadedBytes += readNewData(lastBuffer); emit newDataReady(fh); // inserting in list view is about 3% of total time if (lastBuffer) { emit loaded(fh, loadedBytes, loadTime.elapsed(), true, "", ""); deleteLater(); } else if (isProcExited) { // exited while parsing dbs("Exited while parsing!!!!"); guiUpdateTimer.start(1); } else guiUpdateTimer.start(GUI_UPDATE_INTERVAL); parsing = false; }
// Richiesta connessione TCP in ingresso void DuktoProtocol::newIncomingConnection() { // Recieve connection QTcpSocket* s = mTcpServer->nextPendingConnection(); if(s == NULL) return; // If we are already recieving or sending // Pending header connection (timeout 10 sec) if ((mIsReceiving | mIsSending) || !s->waitForReadyRead(10000)) { s->close(); delete s; return; } // Update GUI receiveFileStart(s->peerAddress().toString()); // set current TCP socket mCurrentSocket = s; // Register socket's event handlers connect(mCurrentSocket, SIGNAL(readyRead()), this, SLOT(readNewData()), Qt::DirectConnection); connect(mCurrentSocket, SIGNAL(disconnected()), this, SLOT(closedConnectionTmp()), Qt::QueuedConnection); // Initialize variables mIsReceiving = true; mTotalReceivedData = 0; mElementSize = -1; mReceivedFiles = new QStringList(); mRootFolderName.clear(); mRootFolderRenamed.clear(); mReceivingText = false; mRecvStatus = FILENAME; // -- Reading General header -- // Entities number to receive mCurrentSocket->read((char*) &mElementsToReceiveCount, sizeof(qint64)); // total size mCurrentSocket->read((char*) &mTotalSize, sizeof(qint64)); // Start reading data on file readNewData(); }
// Chiusura della connessione TCP in ricezione void DuktoProtocol::closedConnection() { // Svuoto il buffer in ricezione readNewData(); // Chiusura eventuale file corrente if (mCurrentFile) { QString name; name = mCurrentFile->fileName(); mCurrentFile->close(); delete mCurrentFile; mCurrentFile = NULL; QFile::remove(name); receiveFileCancelled(); } // Ricezione file conclusa else if (!mReceivingText) receiveFileComplete(mReceivedFiles); // Ricezione testo conclusa else { QString rec = QString::fromUtf8(mTextToReceive); receiveTextComplete(&rec); } // Chiusura socket if (mCurrentSocket) { mCurrentSocket->disconnect(); mCurrentSocket->disconnectFromHost(); mCurrentSocket->close(); mCurrentSocket->deleteLater(); mCurrentSocket = NULL; } // Rilascio memoria delete mReceivedFiles; mReceivedFiles = NULL; // Impostazione stato mIsReceiving = false; }
// Chiusura della connessione TCP in ricezione void DuktoProtocol::closedConnection() { // empty the receive buffer readNewData(); // Closing any current file if (mCurrentFile) { QString name; name = mCurrentFile->fileName(); mCurrentFile->close(); delete mCurrentFile; mCurrentFile = NULL; QFile::remove(name); receiveFileCancelled(); } else if (!mReceivingText) // Receiving file ended { receiveFileComplete(mReceivedFiles, mTotalSize); // TODO: notify for recieving file } else // Receiving text ended { QString rec = QString::fromUtf8(mTextToReceive); receiveTextComplete(&rec, mTotalSize); // TODO: notify for recieving text } // closing socket if (mCurrentSocket) { mCurrentSocket->disconnect(); mCurrentSocket->disconnectFromHost(); mCurrentSocket->close(); mCurrentSocket->deleteLater(); mCurrentSocket = NULL; } // release memory delete mReceivedFiles; mReceivedFiles = NULL; // reset status mIsReceiving = false; }
// Processo di lettura principale void DuktoProtocol::readNewData() { // Temporanea disconnessione per evitare di // ricevere altri segnali mentre ne sto già gestendo uno disconnect(mCurrentSocket, SIGNAL(readyRead()), this, SLOT(readNewData())); // Fino a che ci sono dati da leggere while (mCurrentSocket->bytesAvailable() > 0) { // Verifico se devo leggere un header if (mElementSize == -1) { // Lettura nome char c; while (1) { bool ret = mCurrentSocket->getChar(&c); if (!ret) return; if (c == '\0') break; mPartialName.append(c); } QString name = QString::fromUtf8(mPartialName); mReceivedFiles->append(name); mPartialName.clear(); // Lettura dimensioni mCurrentSocket->read((char*) &mElementSize, sizeof(qint64)); mElementReceivedData = 0; // Se l'elemento corrente è una cartella, la creo e passo all'elemento successivo if (mElementSize == -1) { // Verifico il nome della cartella "root" QString rootName = name.section("/", 0, 0); // Se non ho ancora trattato questa root, lo faccio ora if (mRootFolderName != rootName) { // Verifico se ho già una cartella con questo nome // nel caso trovo un nome alternativo int i = 2; QString originalName = name; while (QFile::exists(name)) name = originalName + " (" + QString::number(i++) + ")"; mRootFolderName = originalName; mRootFolderRenamed = name; } // Se invece l'ho già trattata, allora rinomino questo percorso else if (mRootFolderName != mRootFolderRenamed) name = name.replace(0, name.indexOf('/'), mRootFolderRenamed); // Creo la cartella QDir dir("."); dir.mkpath(name); continue; } // Potrebbe essere un invio di testo else if (name == "___DUKTO___TEXT___") { mReceivingText = true; mTextToReceive.clear(); mCurrentFile = NULL; } // Altrimenti creo il nuovo file else { // Se il file è in una cartella rinominata, devo provvedere di conseguenza if ((name.indexOf('/') != -1) && (name.section("/", 0, 0) == mRootFolderName)) name = name.replace(0, name.indexOf('/'), mRootFolderRenamed); // Se il file esiste già cambio il nome di quello nuovo int i = 2; QString originalName = name; while (QFile::exists(name)) { QFileInfo fi(originalName); name = fi.baseName() + " (" + QString::number(i) + ")." + fi.completeSuffix(); i++; } mCurrentFile = new QFile(name); mCurrentFile->open(QIODevice::WriteOnly); mReceivingText = false; } } // Provo a leggere quanto mi serve per finire il file corrente // (o per svuotare il buffer dei dati ricevuti) qint64 s = (mCurrentSocket->bytesAvailable() > (mElementSize - mElementReceivedData)) ? (mElementSize - mElementReceivedData) : mCurrentSocket->bytesAvailable(); QByteArray d = mCurrentSocket->read(s); mElementReceivedData += d.size(); mTotalReceivedData += d.size(); updateStatus(); // Salvo i dati letti if (!mReceivingText) mCurrentFile->write(d); else mTextToReceive.append(d); // Verifico se ho completato l'elemento corrente if (mElementReceivedData == mElementSize) { // Completato, chiudo il file e mi preparo per il prossimo elemento mElementSize = -1; if (!mReceivingText) { mCurrentFile->deleteLater(); mCurrentFile = NULL; } } } // Riabilitazione segnale connect(mCurrentSocket, SIGNAL(readyRead()), this, SLOT(readNewData()), Qt::DirectConnection); }