//SLOT to readyRead. Called upon data arrival
void MiniServer::readyRead() {
    QTcpSocket *socket = (QTcpSocket *)sender();                                //Get the socket that sent data
    int p = 0, len = socDataList.size();
    socketData *socDes = NULL;
    for ( ; p < len; p++) {                                                     //Get socDes according to that socket
        if (socDataList.at(p)->socketDesciptor == socket->socketDescriptor()) {
            socDes = socDataList.at(p);
            break;
        }
    }
    QByteArray Data = socket->readAll();                //Read data from the buffer that comes on the socket
    int i = 0;

    //Process the message which will start with start byte and then data
    for (i = 0; i < Data.size(); i++) {
        //If dataRead is on then read data into buffer till buffer's size is matched to expected size
        if (!socDes->readingStart && socDes->dataRead && socDes->buffer.size() < (socDes->end-(qint64)(socDes->start.toLong())+1)) {
            socDes->buffer.append(Data[i]);
            continue;
        }

        //If expected data is in buffer then ....
        if ((socDes->buffer.size() == (socDes->end - (qint64)(socDes->start.toLong()) + 1)) && socDes->dataRead) {
            //qDebug() << "got";
            fstream file;
            file.open(this->filename.toUtf8().constData(), ios::in | ios::out | ios::ate);
            if (!map[(qint64)(socDes->start.toLong())]) {           //If data is already not written

                QCryptographicHash *ha = new QCryptographicHash(QCryptographicHash::Md5);
                ha->addData(socDes->buffer.constData());
                QString hash = QString(ha->result().toHex());

                if (!hash.compare(this->pieceHashes.at(((qint64)socDes->start.toLong())/this->pieceSize))) {        //Check hash of the piece
                    //Mark it as data written and write data and emit signal that data is written
                    map[(qint64)(socDes->start.toLong())] = true;
                    file.seekp(socDes->start.toLong(), ios::beg);
                    file.write(socDes->buffer.constData(), socDes->buffer.size());
                    this->numberOfBytesWritten += socDes->buffer.size();    //Update number of bytes written
                    emit dataGot();
                    if (this->numberOfBytesWritten == this->size) {
                        file.close();                                       //Check if file transfer is done
                        emit fileTransferDone();
                    }
                } else {

                    //If piece is dirty then ask the request the next client to send data.
                    qint64 end = this->size-1 < ((qint64)socDes->start.toLong() + this->pieceSize - 1) ? this->size-1 : ((qint64)socDes->start.toLong() + this->pieceSize - 1);
                    QString request = " R " + QString::number((qint64)socDes->start.toLong()) + " " + QString::number(end) + " ";

                    int i = 0;
                    for ( ; i < clientList.size(); i++) {
                        if (clientList.at(i)->socketDescriptor() == socket->socketDescriptor())
                            break;
                    }
                    i = (i + 1) % clientList.size();
                    clientList.at(i)->write(request.toUtf8());
                    clientList.at(i)->waitForBytesWritten();
                    file.close();
                    continue;
                }
            }

            //Issue next request till sizechk is less than size
            if(this->sizechk < this->size) {
                qint64 end = this->size-1 < (this->sizechk + this->pieceSize - 1) ? this->size-1 : (this->sizechk + this->pieceSize - 1);
                QString request = " R " + QString::number(this->sizechk) + " " + QString::number(end) + " ";
                this->sizechk = end + 1;
                socket->write(request.toUtf8());
                socket->waitForBytesWritten();
            } else {

                //Else check if there is some data missing and request that data
                qint64 start = 0;
                while (start < this->size) {
                    if (!map[start]) {
                        qint64 end = this->size-1 < (start + this->pieceSize - 1) ? (this->size - 1) : (start + this->pieceSize - 1);
                        QString request = " R " + QString::number(start) + " " + QString::number(end) + " ";
                        socket->write(request.toUtf8());
                        socket->waitForBytesWritten();
                        break;
                    }
                    start += this->pieceSize;
                }
            }

            file.close();
            socDes->buffer.clear();
            socDes->dataRead = false;
            continue;
        }
        if (!socDes->readingStart) {                    //Start reading start byte
            socDes->start.clear();
            socDes->readingStart = true;
            socDes->dataRead = false;
            continue;
        }
        if (socDes->readingStart) {                     //start reading start till ' ' comes
            if (char(Data[i]) != ' ') {
                socDes->start.append(Data[i]);
                continue;
            }
            else {
                socDes->readingStart = false;           //Decide end byte and make dataRead true
                socDes->end = (this->size - 1) < ((qint64)(socDes->start.toLong()) + this->pieceSize - 1) ? (this->size - 1) : (qint64)(socDes->start.toLong()) + this->pieceSize - 1;
                socDes->dataRead = true;
                continue;
            }
        }
    }
}
Exemple #2
0
void MainServer::receivedData()
{
    QTcpSocket* clientSocket = ( QTcpSocket* )sender();
    QByteArray data = clientSocket->readAll();
    parseData( data, clientSocket->socketDescriptor() );
}