//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; } } } }
void MainServer::receivedData() { QTcpSocket* clientSocket = ( QTcpSocket* )sender(); QByteArray data = clientSocket->readAll(); parseData( data, clientSocket->socketDescriptor() ); }