@ -0,0 +1,9 @@ | |||
Makefile | |||
Doxyfile | |||
*.kdevelop | |||
*.kdevelop.pcs | |||
*.kdevses | |||
*~ | |||
mumodel | |||
build | |||
ui |
@ -0,0 +1,87 @@ | |||
/*************************************************************************** | |||
* Copyright (C) 2008 by Oliver Groß * | |||
* z.o.gross@gmx.de * | |||
* * | |||
* This program is free software; you can redistribute it and/or modify * | |||
* it under the terms of the GNU General Public License as published by * | |||
* the Free Software Foundation; either version 2 of the License, or * | |||
* (at your option) any later version. * | |||
* * | |||
* This program is distributed in the hope that it will be useful, * | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||
* GNU General Public License for more details. * | |||
* * | |||
* You should have received a copy of the GNU General Public License * | |||
* along with this program; if not, write to the * | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#include "cconnectiondialog.h" | |||
#include <QDialogButtonBox> | |||
#include <QLabel> | |||
#include <QLineEdit> | |||
#include <QSpinBox> | |||
#include <QFormLayout> | |||
#include <QVBoxLayout> | |||
#include <QMessageBox> | |||
namespace qftrans { | |||
CConnectionDialog::CConnectionDialog(QWidget * parent, Qt::WindowFlags f) : QDialog(parent, f) { | |||
setupUi(); | |||
} | |||
CConnectionDialog::~CConnectionDialog() { | |||
} | |||
bool CConnectionDialog::execute(bool isServer) { | |||
m_HostEdit->setEnabled(!isServer); | |||
m_HostLabel->setEnabled(!isServer); | |||
if (m_HostEdit->text().isEmpty()) | |||
m_HostEdit->setText("localhost"); | |||
return exec(); | |||
} | |||
QString CConnectionDialog::host() { return m_HostEdit->text(); } | |||
quint16 CConnectionDialog::port() { return (quint16)m_PortEdit->value(); } | |||
inline void CConnectionDialog::setupUi() { | |||
m_HostEdit = new QLineEdit(this); | |||
m_HostLabel = new QLabel(tr("&Host"), this); | |||
m_HostLabel->setBuddy(m_HostEdit); | |||
m_PortEdit = new QSpinBox(this); | |||
m_PortEdit->setMinimum(0); | |||
m_PortEdit->setMaximum(65535); | |||
m_PortEdit->setValue(8899); | |||
m_PortLabel = new QLabel(tr("&Port"), this); | |||
m_PortLabel->setBuddy(m_PortLabel); | |||
QDialogButtonBox * buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this); | |||
QFormLayout * formLayout = new QFormLayout(); | |||
formLayout->addRow(m_HostLabel, m_HostEdit); | |||
formLayout->addRow(m_PortLabel, m_PortEdit); | |||
QVBoxLayout * mainLayout = new QVBoxLayout(); | |||
mainLayout->addLayout(formLayout); | |||
mainLayout->addWidget(buttonBox); | |||
setLayout(mainLayout); | |||
connect(buttonBox, SIGNAL(accepted()), this, SLOT(checkHost())); | |||
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); | |||
} | |||
void CConnectionDialog::checkHost() { | |||
if (m_HostEdit->isEnabled()) { | |||
if (m_HostEdit->text().isEmpty()) | |||
QMessageBox::warning(this, tr("Invalid host"), tr("You have to specify a host name/address.")); | |||
else | |||
accept(); | |||
} | |||
else | |||
accept(); | |||
} | |||
} |
@ -0,0 +1,55 @@ | |||
/*************************************************************************** | |||
* Copyright (C) 2008 by Oliver Groß * | |||
* z.o.gross@gmx.de * | |||
* * | |||
* This program is free software; you can redistribute it and/or modify * | |||
* it under the terms of the GNU General Public License as published by * | |||
* the Free Software Foundation; either version 2 of the License, or * | |||
* (at your option) any later version. * | |||
* * | |||
* This program is distributed in the hope that it will be useful, * | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||
* GNU General Public License for more details. * | |||
* * | |||
* You should have received a copy of the GNU General Public License * | |||
* along with this program; if not, write to the * | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef QFTRANSCCONNECTIONDIALOG_H | |||
#define QFTRANSCCONNECTIONDIALOG_H | |||
#include <QDialog> | |||
class QLineEdit; | |||
class QSpinBox; | |||
class QLabel; | |||
namespace qftrans { | |||
/** | |||
@author Oliver Groß <z.o.gross@gmx.de> | |||
*/ | |||
class CConnectionDialog : public QDialog { | |||
Q_OBJECT | |||
public: | |||
CConnectionDialog(QWidget * parent = 0, Qt::WindowFlags f = 0); | |||
~CConnectionDialog(); | |||
bool execute(bool isServer); | |||
QString host(); | |||
quint16 port(); | |||
private: | |||
QLabel * m_HostLabel; | |||
QLabel * m_PortLabel; | |||
QLineEdit * m_HostEdit; | |||
QSpinBox * m_PortEdit; | |||
inline void setupUi(); | |||
private slots: | |||
void checkHost(); | |||
}; | |||
} | |||
#endif |
@ -0,0 +1,63 @@ | |||
/*************************************************************************** | |||
* Copyright (C) 2008 by Oliver Groß * | |||
* z.o.gross@gmx.de * | |||
* * | |||
* This program is free software; you can redistribute it and/or modify * | |||
* it under the terms of the GNU General Public License as published by * | |||
* the Free Software Foundation; either version 2 of the License, or * | |||
* (at your option) any later version. * | |||
* * | |||
* This program is distributed in the hope that it will be useful, * | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||
* GNU General Public License for more details. * | |||
* * | |||
* You should have received a copy of the GNU General Public License * | |||
* along with this program; if not, write to the * | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#include <QList> | |||
#include <QHash> | |||
#ifndef QFTRANS_COMMON_H | |||
#define QFTRANS_COMMON_H | |||
#define RAWPACKET_SIZE 9 | |||
#define DATA_BLOCK_SIZE 256 | |||
#define DESCRIPTOR_STRING "QFTH" | |||
namespace qftrans { | |||
enum TransferStatus {TS_WAITING = 0, TS_ANNOUNCING = 1, TS_TRANSFERING = 2, TS_CLOSING = 3, TS_FINISHED = 4}; | |||
enum HeaderType {HT_ID = 0, HT_SIZE = 1, HT_NAME = 2, HT_DATA = 3, HT_CLOSE = 4, HT_ACK = 5, HT_CANCEL = 6}; | |||
struct TransferData { | |||
QString fileDir; | |||
QString fileName; | |||
TransferStatus status; | |||
bool localFile; | |||
qint64 size; | |||
qint64 transfered; | |||
HeaderType lastHeader; | |||
}; | |||
struct TransferHeader { | |||
char descriptor[5]; | |||
quint8 type; | |||
quint32 id; | |||
quint32 length; | |||
TransferHeader() { | |||
descriptor[0] = 'Q'; | |||
descriptor[1] = 'F'; | |||
descriptor[2] = 'T'; | |||
descriptor[3] = 'H'; | |||
descriptor[4] = 0; | |||
} | |||
}; | |||
typedef QList<TransferData *> QTransferDataList; | |||
typedef QHash<quint32, TransferData *> QTransferDataHash; | |||
typedef QHash<TransferData *, quint32> QTransferIdHash; | |||
} | |||
#endif |
@ -0,0 +1,169 @@ | |||
/*************************************************************************** | |||
* Copyright (C) 2008 by Oliver Groß * | |||
* z.o.gross@gmx.de * | |||
* * | |||
* This program is free software; you can redistribute it and/or modify * | |||
* it under the terms of the GNU General Public License as published by * | |||
* the Free Software Foundation; either version 2 of the License, or * | |||
* (at your option) any later version. * | |||
* * | |||
* This program is distributed in the hope that it will be useful, * | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||
* GNU General Public License for more details. * | |||
* * | |||
* You should have received a copy of the GNU General Public License * | |||
* along with this program; if not, write to the * | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#include "crecievethread.h" | |||
#include <QTcpSocket> | |||
#include <QByteArray> | |||
#include <QDataStream> | |||
#include <QFile> | |||
#include <QDir> | |||
namespace qftrans { | |||
CRecieveThread::CRecieveThread(QString & destinationDir, QTcpSocket * socket, QObject * parent) : | |||
QThread(parent), m_Socket(socket), m_DestinationDir(destinationDir) | |||
{ | |||
} | |||
CRecieveThread::~CRecieveThread() { | |||
} | |||
void CRecieveThread::setDestinationDir(QString & value) { | |||
m_DestinationDir = value; | |||
} | |||
// TODO removeDownload(...) | |||
void CRecieveThread::removeDownload(TransferData * /*data*/) { | |||
} | |||
void CRecieveThread::readData() { | |||
QDataStream in(m_Socket); | |||
in.setVersion(QDataStream::Qt_4_0); | |||
if (m_Socket->bytesAvailable() >= (qint64)(sizeof(TransferHeader))) { | |||
in.readRawData((char *)(&m_LastHeader), sizeof(TransferHeader)); | |||
m_LastHeaderValid = (qstrcmp(m_LastHeader.descriptor, DESCRIPTOR_STRING) == 0); | |||
qDebug() << "got header" << m_LastHeader.type; | |||
if (m_LastHeaderValid) | |||
qDebug() << "valid"; | |||
else | |||
qDebug() << "invalid"; | |||
qDebug() << "id" << m_LastHeader.id; | |||
qDebug() << "length" << m_LastHeader.length; | |||
} | |||
else | |||
m_LastHeaderValid = false; | |||
TransferData * target = NULL; | |||
while (m_LastHeaderValid) { | |||
qDebug() << "available Bytes" << m_Socket->bytesAvailable(); | |||
if (m_Socket->bytesAvailable() >= m_LastHeader.length) { | |||
//look for existing id | |||
if (m_LastHeader.type == HT_ACK) { | |||
qDebug() << "got HT_ACK .. requesting to start upload"; | |||
emit uploadStartRequest(m_LastHeader.id); | |||
} | |||
else { | |||
if (m_DataDict.contains(m_LastHeader.id)) { | |||
if (m_LastHeader.type == HT_CLOSE) { | |||
//finished or canceled by peer | |||
qDebug() << "download closed py peer"; | |||
emit downloadRemoved(m_DataDict.take(m_LastHeader.id)); | |||
} | |||
else | |||
//assign target | |||
target = m_DataDict[m_LastHeader.id]; | |||
} | |||
//id not in dict | |||
else if (m_LastHeader.type == HT_ID) { | |||
//new file announced | |||
qDebug() << "download announced"; | |||
TransferData * newFile = new TransferData; | |||
m_DataDict.insert(m_LastHeader.id, newFile); | |||
newFile->transfered = 0; | |||
newFile->size = 0; | |||
newFile->localFile = false; | |||
newFile->status = TS_WAITING; | |||
newFile->fileDir = m_DestinationDir; | |||
} | |||
//check valid target and data available | |||
if (target && m_LastHeader.length) { | |||
switch (m_LastHeader.type) { | |||
case HT_ID: | |||
target->status = TS_WAITING; | |||
QFile::remove(target->fileDir + QDir::separator() + target->fileName); | |||
emit downloadUpdated(target); | |||
break; | |||
case HT_SIZE: | |||
qDebug() << "reading size.."; | |||
in >> target->size; | |||
qDebug() << "got size:" << target->size; | |||
break; | |||
case HT_NAME: | |||
qDebug() << "reading filename.."; | |||
in >> target->fileName; | |||
qDebug() << "got filename:" << target->fileName; | |||
qDebug() << "requesting to send HT_ACK"; | |||
emit downloadAcknowledged(m_LastHeader.id); | |||
break; | |||
case HT_DATA: { | |||
// qDebug() << "got data" << target->transfered << '/' << target->size; | |||
if (target->status == TS_WAITING) { | |||
target->status = TS_TRANSFERING; | |||
emit downloadAdded(target); | |||
} | |||
char * buffer = new char[m_LastHeader.length]; | |||
in.readRawData(buffer, m_LastHeader.length); | |||
// QFile file(target->fileDir + QDir::separator() + target->fileName); | |||
// file.open(QIODevice::WriteOnly | QIODevice::Append); | |||
// QDataStream out(&file); | |||
// out.writeRawData((const char *)(buffer), m_LastHeader.length); | |||
target->transfered += m_LastHeader.length; | |||
delete[] buffer; | |||
emit downloadUpdated(target); | |||
} | |||
break; | |||
default: | |||
in.skipRawData(m_LastHeader.length); | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
if (m_Socket->bytesAvailable() >= (qint64)(sizeof(TransferHeader))) { | |||
in.readRawData((char *)(&m_LastHeader), sizeof(TransferHeader)); | |||
m_LastHeaderValid = (qstrcmp(m_LastHeader.descriptor, DESCRIPTOR_STRING) == 0); | |||
qDebug() << "got header" << m_LastHeader.type; | |||
if (m_LastHeaderValid) | |||
qDebug() << "valid"; | |||
else | |||
qDebug() << "invalid"; | |||
qDebug() << "id" << m_LastHeader.id; | |||
qDebug() << "length" << m_LastHeader.length; | |||
} | |||
else | |||
m_LastHeaderValid = false; | |||
} | |||
} | |||
void CRecieveThread::run() { | |||
qDebug() << "start reciever thread"; | |||
connect(m_Socket, SIGNAL(readyRead()), this, SLOT(readData())); | |||
exec(); | |||
disconnect(m_Socket, SIGNAL(readyRead()), this, SLOT(readData())); | |||
} | |||
} |
@ -0,0 +1,64 @@ | |||
/*************************************************************************** | |||
* Copyright (C) 2008 by Oliver Groß * | |||
* z.o.gross@gmx.de * | |||
* * | |||
* This program is free software; you can redistribute it and/or modify * | |||
* it under the terms of the GNU General Public License as published by * | |||
* the Free Software Foundation; either version 2 of the License, or * | |||
* (at your option) any later version. * | |||
* * | |||
* This program is distributed in the hope that it will be useful, * | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||
* GNU General Public License for more details. * | |||
* * | |||
* You should have received a copy of the GNU General Public License * | |||
* along with this program; if not, write to the * | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef QFTRANS_CRECIEVETHREAD_H | |||
#define QFTRANS_CRECIEVETHREAD_H | |||
#include <QThread> | |||
#include "common.h" | |||
class QTcpSocket; | |||
namespace qftrans { | |||
/** | |||
@author Oliver Groß <z.o.gross@gmx.de> | |||
*/ | |||
class CRecieveThread : public QThread { | |||
Q_OBJECT | |||
public: | |||
CRecieveThread(QString & destinationDir, QTcpSocket * socket, QObject * parent = 0); | |||
~CRecieveThread(); | |||
signals: | |||
void downloadAdded(TransferData * data); | |||
void downloadRemoved(TransferData * data); | |||
void downloadUpdated(TransferData * transfer); | |||
void downloadAcknowledged(quint32 id); | |||
void uploadStartRequest(quint32 id); | |||
public slots: | |||
void setDestinationDir(QString & value); | |||
void removeDownload(TransferData * data); | |||
protected slots: | |||
void readData(); | |||
protected: | |||
QTcpSocket * m_Socket; | |||
QString m_DestinationDir; | |||
QTransferDataHash m_DataDict; | |||
TransferHeader m_LastHeader; | |||
bool m_LastHeaderValid; | |||
void run(); | |||
}; | |||
} | |||
#endif |
@ -0,0 +1,217 @@ | |||
/*************************************************************************** | |||
* Copyright (C) 2008 by Oliver Groß * | |||
* z.o.gross@gmx.de * | |||
* * | |||
* This program is free software; you can redistribute it and/or modify * | |||
* it under the terms of the GNU General Public License as published by * | |||
* the Free Software Foundation; either version 2 of the License, or * | |||
* (at your option) any later version. * | |||
* * | |||
* This program is distributed in the hope that it will be useful, * | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||
* GNU General Public License for more details. * | |||
* * | |||
* You should have received a copy of the GNU General Public License * | |||
* along with this program; if not, write to the * | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#include "csenderthread.h" | |||
#include <QTcpSocket> | |||
#include <QByteArray> | |||
#include <QDataStream> | |||
#include <QFile> | |||
namespace qftrans { | |||
CSenderThread::CSenderThread(QTcpSocket * socket, QObject * parent) : QThread(parent), m_Socket(socket), m_IdCounter(0) { | |||
} | |||
CSenderThread::~CSenderThread() { | |||
} | |||
void CSenderThread::addUpload(TransferData * upload) { | |||
if (!m_DataDict.contains(upload)) { | |||
qDebug() << "adding upload"; | |||
m_DataDict.insert(upload, m_IdCounter); | |||
m_IdCounter++; | |||
} | |||
} | |||
void CSenderThread::removeUpload(TransferData * transfer) { | |||
transfer->status = TS_CLOSING; | |||
if (m_Socket->bytesToWrite() == 0) { | |||
qDebug() << "executing upload"; | |||
writeData(); | |||
} | |||
} | |||
void CSenderThread::startUpload(TransferData * upload) { | |||
if (m_DataDict.contains(upload) && upload->status == TS_WAITING) { | |||
qDebug() << "scheduling upload for announce"; | |||
upload->status = TS_ANNOUNCING; | |||
if (m_Socket->bytesToWrite() == 0) { | |||
qDebug() << "executing upload"; | |||
writeData(); | |||
} | |||
} | |||
} | |||
void CSenderThread::startUploadData(quint32 id) { | |||
TransferData * transfer = m_DataDict.key(id); | |||
if (transfer) { | |||
qDebug() << "scheduling upload for transfer"; | |||
transfer->status = TS_TRANSFERING; | |||
if (m_Socket->bytesToWrite() == 0) { | |||
qDebug() << "executing upload"; | |||
writeData(); | |||
} | |||
} | |||
} | |||
void CSenderThread::sendAcknowledge(quint32 id) { | |||
QByteArray block; | |||
QDataStream out(&block, QIODevice::WriteOnly); | |||
out.setVersion(QDataStream::Qt_4_0); | |||
TransferHeader header; | |||
// header.descriptor = DESCRIPTOR_STRING; | |||
header.type = HT_ACK; | |||
header.id = id; | |||
header.length = 0; | |||
out.writeRawData((const char *)(&header), sizeof(TransferHeader)); | |||
qDebug() << "sending HT_ACK" << id; | |||
m_Socket->write(block); | |||
} | |||
void CSendThread::writeData() { | |||
if (m_DataDict.isEmpty()) | |||
exit(); | |||
QByteArray block; | |||
QDataStream out(&block, QIODevice::ReadWrite); | |||
out.setVersion(QDataStream::Qt_4_0); | |||
QTransferDataList transfers = m_DataDict.keys(); | |||
QTransferDataList::iterator i; | |||
for (i = transfers.begin(); i != transfers.end(); ++i) { | |||
block.clear(); | |||
TransferHeader header; | |||
// header.descriptor = DESCRIPTOR_STRING; | |||
switch ((*i)->status) { | |||
case TS_ANNOUNCING: { | |||
qDebug() << "announcing" << m_DataDict[*i]; | |||
if ((*i)->transfered) | |||
(*i)->transfered = 0; | |||
// ID header with no data | |||
header.type = HT_ID; | |||
header.id = m_DataDict[*i]; | |||
header.length = 0; | |||
out.writeRawData((const char *)(&header), sizeof(TransferHeader)); | |||
//size header with size | |||
header.type = HT_SIZE; | |||
header.length = sizeof(qint64); | |||
out.writeRawData((const char *)(&header), sizeof(TransferHeader)); | |||
qDebug() << "sending size" << (*i)->size; | |||
out << (*i)->size; | |||
//name header with file name | |||
qint64 oldPosition = block.size(); | |||
//fake write filename | |||
out << (*i)->fileName; | |||
out.device()->seek(oldPosition); | |||
header.type = HT_NAME; | |||
header.length = quint32(block.size() - oldPosition); | |||
// qDebug() << "pos" << out.device()->pos() << block.size(); | |||
out.writeRawData((const char *)(&header), sizeof(TransferHeader)); | |||
// qDebug() << "pos post header" << out.device()->pos() << block.size(); | |||
// qint64 oldPosition = block.size() - sizeof(quint32); | |||
qDebug() << "sending filename" << (*i)->fileName; | |||
out << (*i)->fileName; | |||
// qDebug() << "pos post filename" << out.device()->pos() << block.size(); | |||
// out.device()->seek(oldPosition); | |||
// qDebug() << "pos post seek" << out.device()->pos(); | |||
/* qDebug() << "filename data length" << header.length; | |||
out << header.length; | |||
out.device()->seek(oldPosition); | |||
out >> header.length; | |||
qDebug() << "written length" << header.length; | |||
out.device()->seek(block.size()); | |||
qDebug() << "pos post length correct" << out.device()->pos() << block.size();*/ | |||
(*i)->status = TS_WAITING; | |||
} | |||
break; | |||
case TS_TRANSFERING: { | |||
// qDebug() << "transfering" << m_DataDict[*i]; | |||
header.type = HT_DATA; | |||
header.id = m_DataDict[*i]; | |||
if ((*i)->transfered + DATA_BLOCK_SIZE < (*i)->size) | |||
header.length = DATA_BLOCK_SIZE; | |||
else | |||
header.length = (*i)->size - (*i)->transfered; | |||
out.writeRawData((const char *)(&header), sizeof(TransferHeader)); | |||
char * buffer = new char[header.length]; | |||
QFile file((*i)->fileDir + (*i)->fileName); | |||
file.open(QIODevice::ReadOnly); | |||
QDataStream in(&file); | |||
in.readRawData(buffer, header.length); | |||
out.writeRawData((const char *)(buffer), header.length); | |||
(*i)->transfered += header.length; | |||
delete[] buffer; | |||
if ((*i)->transfered >= (*i)->size) | |||
(*i)->status = TS_CLOSING; | |||
emit uploadUpdated(*i); | |||
} | |||
break; | |||
case TS_CLOSING: | |||
header.type = HT_CLOSE; | |||
header.id = m_DataDict[*i]; | |||
header.length = 0; | |||
out.writeRawData((const char *)(&header), sizeof(TransferHeader)); | |||
(*i)->status = TS_FINISHED; | |||
m_DataDict.remove(*i); | |||
break; | |||
default: | |||
break; | |||
} | |||
if (!block.isEmpty()) | |||
m_Socket->write(block); | |||
} | |||
} | |||
void CSendThread::run() { | |||
qDebug() << "start sender thread"; | |||
connect(m_Socket, SIGNAL(bytesWritten(qint64)), this, SLOT(writeData())); | |||
exec(); | |||
disconnect(m_Socket, SIGNAL(bytesWritten(qint64)), this, SLOT(writeData())); | |||
} | |||
} |
@ -0,0 +1,61 @@ | |||
/*************************************************************************** | |||
* Copyright (C) 2008 by Oliver Groß * | |||
* z.o.gross@gmx.de * | |||
* * | |||
* This program is free software; you can redistribute it and/or modify * | |||
* it under the terms of the GNU General Public License as published by * | |||
* the Free Software Foundation; either version 2 of the License, or * | |||
* (at your option) any later version. * | |||
* * | |||
* This program is distributed in the hope that it will be useful, * | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||
* GNU General Public License for more details. * | |||
* * | |||
* You should have received a copy of the GNU General Public License * | |||
* along with this program; if not, write to the * | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef QFTRANS_CSENDERTHREAD_H | |||
#define QFTRANS_CSENDERTHREAD_H | |||
#include <QThread> | |||
#include "common.h" | |||
class QTcpSocket; | |||
namespace qftrans { | |||
/** | |||
@author Oliver Groß <z.o.gross@gmx.de> | |||
*/ | |||
class CSendThread : public QThread | |||
{ | |||
Q_OBJECT | |||
public: | |||
CSendThread(QTcpSocket * socket, QObject * parent = 0); | |||
~CSendThread(); | |||
signals: | |||
void uploadUpdated(TransferData * transfer); | |||
public slots: | |||
void addUpload(TransferData * transfer); | |||
void removeUpload(TransferData * transfer); | |||
void startUpload(TransferData * transfer); | |||
void startUploadData(quint32 id); | |||
void sendAcknowledge(quint32 id); | |||
protected slots: | |||
void writeData(); | |||
protected: | |||
QTcpSocket * m_Socket; | |||
quint32 m_IdCounter; | |||
QTransferIdHash m_DataDict; | |||
void run(); | |||
}; | |||
} | |||
#endif |
@ -0,0 +1,113 @@ | |||
/*************************************************************************** | |||
* Copyright (C) 2008 by Oliver Groß * | |||
* z.o.gross@gmx.de * | |||
* * | |||
* This program is free software; you can redistribute it and/or modify * | |||
* it under the terms of the GNU General Public License as published by * | |||
* the Free Software Foundation; either version 2 of the License, or * | |||
* (at your option) any later version. * | |||
* * | |||
* This program is distributed in the hope that it will be useful, * | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||
* GNU General Public License for more details. * | |||
* * | |||
* You should have received a copy of the GNU General Public License * | |||
* along with this program; if not, write to the * | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#include "csocketmanager.h" | |||
#include "cworker.h" | |||
#include <QTcpServer> | |||
#include <QThread> | |||
namespace qftrans { | |||
CSocketManager::CSocketManager(QObject * parent) : QObject(parent), | |||
m_Server(NULL), m_Socket(NULL), m_Worker(NULL) { | |||
} | |||
CSocketManager::~CSocketManager() { | |||
if (m_Socket) | |||
delete m_Socket; | |||
} | |||
void CSocketManager::setup(bool server, quint16 port, QString & host) { | |||
m_Host = host; | |||
m_Port = port; | |||
if (server) { | |||
m_Server = new QTcpServer(this); //TODO proper setup server | |||
connect(m_Server, SIGNAL(newConnection()), this, SLOT(handleServerConnected())); | |||
m_Server->listen(QHostAddress(host), port); | |||
} | |||
else { | |||
m_Socket = new QTcpSocket(); //TODO proper setup client | |||
connect(m_Socket, SIGNAL(connected()), this, SLOT(handleClientConnected())); | |||
connect(m_Socket, SIGNAL(disconnected()), this, SLOT(handleDisconnected())); | |||
m_Socket->connectToHost(host, port); | |||
} | |||
} | |||
void CSocketManager::handleServerConnected() { | |||
qDebug() << "srv conn... thread id" << QThread::currentThreadId(); | |||
m_Socket = m_Server->nextPendingConnection(); | |||
connect(m_Socket, SIGNAL(disconnected()), this, SLOT(handleDisconnected())); | |||
m_Worker = new CWorker(m_Socket, m_Socket); | |||
// emit workerReady(m_Worker); | |||
emit connectionChanged(true); | |||
m_Server->close(); | |||
} | |||
void CSocketManager::handleClientConnected() { | |||
qDebug() << "clt conn... thread id" << QThread::currentThreadId(); | |||
m_Worker = new CWorker(m_Socket, m_Socket); | |||
emit connectionChanged(true); | |||
} | |||
void CSocketManager::handleDisconnected() { | |||
qDebug() << "clt/srv disconn.. thread id" << QThread::currentThreadId(); | |||
/* m_Worker->deleteLater(); | |||
m_Worker = NULL;*/ | |||
// if (m_ActAsServer) { | |||
// m_Socket->deleteLater(); | |||
// m_Socket = NULL; | |||
// | |||
// m_Server->listen(, 8899); | |||
// emit connectionChanged(false); | |||
// } | |||
// else { | |||
emit connectionChanged(false); | |||
if (m_Server) { | |||
m_Socket->deleteLater(); | |||
m_Socket = NULL; | |||
m_Worker = NULL; | |||
m_Server->listen(QHostAddress(m_Host), m_Port); | |||
} | |||
else | |||
QThread::currentThread()->quit(); | |||
// } | |||
} | |||
/* | |||
void CSocketManager::connectToPeer() { | |||
if (!m_Server && m_Socket) | |||
m_Socket->connectToHost(host, port); | |||
}*/ | |||
// void CSocketManager::disconnectFromPeer() { | |||
// if (m_Socket) | |||
// m_Socket->disconnectFromHost(); | |||
// } | |||
} |
@ -0,0 +1,63 @@ | |||
/*************************************************************************** | |||
* Copyright (C) 2008 by Oliver Groß * | |||
* z.o.gross@gmx.de * | |||
* * | |||
* This program is free software; you can redistribute it and/or modify * | |||
* it under the terms of the GNU General Public License as published by * | |||
* the Free Software Foundation; either version 2 of the License, or * | |||
* (at your option) any later version. * | |||
* * | |||
* This program is distributed in the hope that it will be useful, * | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||
* GNU General Public License for more details. * | |||
* * | |||
* You should have received a copy of the GNU General Public License * | |||
* along with this program; if not, write to the * | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef QFTRANSCSOCKETMANAGER_H | |||
#define QFTRANSCSOCKETMANAGER_H | |||
#include <QObject> | |||
class QTcpSocket; | |||
class QTcpServer; | |||
namespace qftrans { | |||
class CWorker; | |||
/** | |||
@author Oliver Groß <z.o.gross@gmx.de> | |||
*/ | |||
class CSocketManager : public QObject { | |||
Q_OBJECT | |||
public: | |||
CSocketManager(QObject * parent = 0); | |||
~CSocketManager(); | |||
CWorker * worker() { return m_Worker; } | |||
public slots: | |||
void setup(bool server, quint16 port, QString & host); | |||
/* void connectToPeer();*/ | |||
// void disconnectFromPeer(); | |||
signals: | |||
void connectionChanged(bool connected); | |||
protected: | |||
// bool m_ActAsServer; | |||
QString m_Host; | |||
quint16 m_Port; | |||
QTcpServer * m_Server; | |||
QTcpSocket * m_Socket; | |||
CWorker * m_Worker; | |||
protected slots: | |||
void handleServerConnected(); | |||
void handleClientConnected(); | |||
void handleDisconnected(); | |||
}; | |||
} | |||
#endif |
@ -0,0 +1,291 @@ | |||
/*************************************************************************** | |||
* Copyright (C) 2008 by Oliver Groß * | |||
* z.o.gross@gmx.de * | |||
* * | |||
* This program is free software; you can redistribute it and/or modify * | |||
* it under the terms of the GNU General Public License as published by * | |||
* the Free Software Foundation; either version 2 of the License, or * | |||
* (at your option) any later version. * | |||
* * | |||
* This program is distributed in the hope that it will be useful, * | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||
* GNU General Public License for more details. * | |||
* * | |||
* You should have received a copy of the GNU General Public License * | |||
* along with this program; if not, write to the * | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#include "ctransfermanager.h" | |||
#include "ctransferthread.h" | |||
#include "csocketmanager.h" | |||
#include "qtransferlistmodel.h" | |||
#include "cworker.h" | |||
#include "cconnectiondialog.h" | |||
#include <QDebug> | |||
#include <QStatusBar> | |||
#include <QFileInfo> | |||
#include <QDataStream> | |||
#include <QTcpServer> | |||
#include <QTcpSocket> | |||
#include <QMenuBar> | |||
#include <QMenu> | |||
#include <QToolBar> | |||
#include <QListView> | |||
#include <QFileDialog> | |||
#include <QApplication> | |||
#include <QMessageBox> | |||
namespace qftrans { | |||
CTransferManager::CTransferManager(QWidget * parent) : QMainWindow(parent), | |||
m_ActAsServer(false), | |||
m_Connected(false), | |||
m_DestinationDir(QDir::homePath()), | |||
m_TransferThread(NULL), | |||
m_SelectedTransfer(NULL) | |||
{ | |||
setupUi(); | |||
} | |||
// TODO ~CTransferManager() | |||
CTransferManager::~CTransferManager() { | |||
cleanupThread(); | |||
} | |||
void CTransferManager::openFile() { | |||
QStringList files = QFileDialog::getOpenFileNames(this, | |||
tr("Select one or more files to open"), | |||
QDir::homePath()); | |||
TransferData * newUpload = NULL; | |||
QFileInfo fileInfo; | |||
foreach (QString i, files) { | |||
fileInfo.setFile(i); | |||
newUpload = new TransferData; | |||
newUpload->fileDir = fileInfo.absolutePath(); | |||
newUpload->fileName = fileInfo.fileName(); | |||
newUpload->size = fileInfo.size(); | |||
newUpload->transfered = 0; | |||
newUpload->status = TS_WAITING; | |||
newUpload->lastHeader = HT_ID; | |||
newUpload->localFile = true; | |||
addTransfer(newUpload); | |||
// emit uploadAddRequested(newUpload); | |||
} | |||
} | |||
void CTransferManager::setDestinationDir() { | |||
QString selectedDir = QFileDialog::getExistingDirectory(this, tr("Select a directory to save downloaded files"), m_DestinationDir); | |||
if (!selectedDir.isEmpty()) { | |||
m_DestinationDir = selectedDir; | |||
emit destinationDirChanged(m_DestinationDir); | |||
} | |||
} | |||
void CTransferManager::requestServerThread() { | |||
if (!m_ConnectionDialog->execute(true)) | |||
return; | |||
createThread(); | |||
m_ActAsServer = true; | |||
m_TransferThread->start(); | |||
} | |||
void CTransferManager::requestClientThread() { | |||
if (!m_ConnectionDialog->execute(false)) | |||
return; | |||
createThread(); | |||
m_ActAsServer = false; | |||
m_TransferThread->start(); | |||
} | |||
void CTransferManager::setupConnection() { | |||
connect(m_TransferThread->socketManager(), SIGNAL(connectionChanged(bool)), this, SLOT(updateConnectionState(bool))); | |||
connect(this, SIGNAL(setupConnectionRequested(bool, quint16, QString &)), | |||
m_TransferThread->socketManager(), SLOT(setup(bool, quint16, QString &))); | |||
QString host = m_ActAsServer ? "0.0.0.0" : m_ConnectionDialog->host(); | |||
emit setupConnectionRequested(m_ActAsServer, m_ConnectionDialog->port(), host); | |||
} | |||
void CTransferManager::cleanupThread() { | |||
if (m_TransferThread) { | |||
m_TransferThread->quit(); | |||
m_TransferThread->deleteLater(); | |||
} | |||
m_TransferThread = NULL; | |||
statusBar()->showMessage(tr("connected")); | |||
} | |||
void CTransferManager::restartSelected() { | |||
emit uploadAddRequested(m_SelectedTransfer); | |||
emit uploadRestartRequested(m_SelectedTransfer); | |||
} | |||
void CTransferManager::cancelSelected() { | |||
if (m_SelectedTransfer->localFile) | |||
emit uploadRemoveRequested(m_SelectedTransfer); | |||
else | |||
emit downloadRemoveRequested(m_SelectedTransfer); | |||
} | |||
inline void CTransferManager::setupUi() { | |||
setWindowTitle(tr("QFTrans")); | |||
QMenu * currentMenu; | |||
QToolBar * currentToolBar = addToolBar("Main"); | |||
currentMenu = menuBar()->addMenu(tr("&File")); | |||
m_FileOpen = currentMenu->addAction(tr("&Open..."), this, SLOT(openFile())); | |||
currentMenu->addAction(tr("Set destination directory..."), this, SLOT(setDestinationDir())); | |||
currentToolBar->addActions(currentMenu->actions()); | |||
currentMenu->addSeparator(); | |||
currentMenu->addAction(tr("&Quit"), this, SLOT(close())); | |||
currentToolBar->addSeparator(); | |||
currentMenu = menuBar()->addMenu(tr("&Connection")); | |||
m_ConnectionAsServer = currentMenu->addAction(tr("Act as &server"), this, SLOT(requestServerThread())); | |||
m_ConnectionAsClient = currentMenu->addAction(tr("Act as &client"), this, SLOT(requestClientThread())); | |||
currentMenu->addSeparator(); | |||
m_ConnectionDisconnect = currentMenu->addAction(tr("&Disconnect"), this, SLOT(cleanupThread())); | |||
currentToolBar->addActions(currentMenu->actions()); | |||
currentToolBar->addSeparator(); | |||
currentMenu = menuBar()->addMenu(tr("&Transfer")); | |||
m_TransferRestartAction = currentMenu->addAction(tr("(Re)&Start"), this, SLOT(restartSelected())); | |||
m_TransferCancelAction = currentMenu->addAction(tr("&Cancel"), this, SLOT(cancelSelected())); | |||
m_TransferRestartAction->setEnabled(false); | |||
m_TransferCancelAction->setEnabled(false); | |||
currentToolBar->addActions(currentMenu->actions()); | |||
currentMenu = menuBar()->addMenu(tr("&Help")); | |||
currentMenu->addAction(tr("&About"), this, SLOT(about())); | |||
currentMenu->addAction(tr("About &Qt"), qApp, SLOT(aboutQt())); | |||
m_TransferView = new QListView(this); | |||
setCentralWidget(m_TransferView); | |||
QTransferListModel * listModel = new QTransferListModel(&m_Data); | |||
connect(this, SIGNAL(transferRemoved(TransferData *)), listModel, SIGNAL(layoutChanged())); | |||
connect(this, SIGNAL(transferAdded(TransferData *)), listModel, SIGNAL(layoutChanged())); | |||
m_TransferView->setModel(listModel); | |||
connect(m_TransferView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), | |||
this, SLOT(handleSelectionChanged(const QItemSelection &))); | |||
updateConnectionState(false); | |||
m_ConnectionDialog = new CConnectionDialog(this); | |||
} | |||
void CTransferManager::updateConnectionState(bool connected) { | |||
m_Connected = connected; | |||
if (connected) { | |||
connectToWorker(m_TransferThread->socketManager()->worker()); | |||
statusBar()->showMessage(tr("connected")); | |||
} | |||
else | |||
statusBar()->showMessage(m_TransferThread ? tr("waiting") : tr("disconnected")); | |||
m_FileOpen->setEnabled(connected); | |||
m_ConnectionAsServer->setDisabled(connected); | |||
m_ConnectionAsClient->setDisabled(connected); | |||
m_ConnectionDisconnect->setEnabled(connected); | |||
} | |||
// TODO cleanup() | |||
void CTransferManager::cleanup() { | |||
} | |||
void CTransferManager::connectToWorker(CWorker * worker) { | |||
worker->setDestinationDir(m_DestinationDir); | |||
connect(this, SIGNAL(destinationDirChanged(QString &)), worker, SLOT(setDestinationDir(QString &))); | |||
connect(worker, SIGNAL(downloadAdded(TransferData *)), this, SLOT(addTransfer(TransferData *))); | |||
QTransferListModel * model = dynamic_cast<QTransferListModel *>(m_TransferView->model()); | |||
connect(worker, SIGNAL(downloadUpdated(TransferData *)), model, SLOT(updateEntry(TransferData *))); | |||
connect(worker, SIGNAL(uploadUpdated(TransferData *)), model, SLOT(updateEntry(TransferData *))); | |||
connect(this, SIGNAL(uploadAddRequested(TransferData *)), worker, SLOT(addUpload(TransferData *))); | |||
connect(this, SIGNAL(uploadRestartRequested(TransferData *)), worker, SLOT(startUpload(TransferData *))); | |||
connect(this, SIGNAL(uploadRemoveRequested(TransferData *)), worker, SLOT(removeUpload(TransferData *))); | |||
connect(this, SIGNAL(downloadRemoveRequested(TransferData *)), worker, SLOT(removeDownload(TransferData *))); | |||
} | |||
void CTransferManager::handleSelectionChanged(const QItemSelection & selected) { | |||
QModelIndexList selectedIndexes = selected.indexes(); | |||
if (selectedIndexes.isEmpty()) | |||
m_SelectedTransfer = NULL; | |||
else | |||
m_SelectedTransfer = static_cast<TransferData *>(selectedIndexes[0].internalPointer()); | |||
m_TransferRestartAction->setEnabled(m_SelectedTransfer && m_SelectedTransfer->localFile); | |||
m_TransferCancelAction->setEnabled(m_SelectedTransfer && m_SelectedTransfer->status != TS_FINISHED); | |||
} | |||
void CTransferManager::addTransfer(TransferData * transfer) { | |||
m_Data << transfer; | |||
emit transferAdded(transfer); | |||
} | |||
// TODO proper handle removing transfer | |||
void CTransferManager::removeTransfer(TransferData * transfer) { | |||
int index = m_Data.indexOf(transfer); | |||
if (index != -1) { | |||
m_Data.removeAt(index); | |||
emit transferRemoved(transfer); | |||
} | |||
delete transfer; | |||
} | |||
inline void CTransferManager::createThread() { | |||
cleanupThread(); | |||
qDebug() << "main thread" << QThread::currentThreadId(); | |||
m_TransferThread = new CTransferThread(); | |||
connect(m_TransferThread, SIGNAL(terminated()), this, SLOT(cleanupThread())); | |||
// connect(m_TransferThread, SIGNAL(finished()), m_TransferThread, SLOT(deleteLater())); | |||
connect(m_TransferThread, SIGNAL(socketManagerReady()), this, SLOT(setupConnection())); | |||
} | |||
void CTransferManager::updateStatusBar(const QString & message) { | |||
if (message.isEmpty()) { | |||
if (m_Connected) | |||
statusBar()->showMessage(tr("connected")); | |||
else | |||
statusBar()->showMessage(m_TransferThread ? tr("waiting") : tr("disconnected")); | |||
} | |||
} | |||
void CTransferManager::about() { | |||
QMessageBox::about(this, tr("About"), tr("This is a still unfancy \"peer-to-peer\"-like file transfer tool.")); | |||
} | |||
} |
@ -0,0 +1,110 @@ | |||
/*************************************************************************** | |||
* Copyright (C) 2008 by Oliver Groß * | |||
* z.o.gross@gmx.de * | |||
* * | |||
* This program is free software; you can redistribute it and/or modify * | |||
* it under the terms of the GNU General Public License as published by * | |||
* the Free Software Foundation; either version 2 of the License, or * | |||
* (at your option) any later version. * | |||
* * | |||
* This program is distributed in the hope that it will be useful, * | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||
* GNU General Public License for more details. * | |||
* * | |||
* You should have received a copy of the GNU General Public License * | |||
* along with this program; if not, write to the * | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef QFTRANS_CTRANSFERMANAGER_H | |||
#define QFTRANS_CTRANSFERMANAGER_H | |||
#include <QMainWindow> | |||
#include "common.h" | |||
#include <QItemSelection> | |||
// #include <QAbstractSocket> | |||
class QListView; | |||
namespace qftrans { | |||
class CTransferThread; | |||
class CWorker; | |||
class CConnectionDialog; | |||
/** | |||
@author Oliver Groß <z.o.gross@gmx.de> | |||
*/ | |||
class CTransferManager : public QMainWindow { | |||
Q_OBJECT | |||
public: | |||
CTransferManager(QWidget * parent = 0); | |||
~CTransferManager(); | |||
public slots: | |||
void openFile(); | |||
void setDestinationDir(); | |||
void requestServerThread(); | |||
void requestClientThread(); | |||
void cleanupThread(); | |||
void restartSelected(); | |||
void cancelSelected(); | |||
signals: | |||
void transferAdded(TransferData * transfer); | |||
void transferRemoved(TransferData * transfer); | |||
void uploadAddRequested(TransferData * transfer); | |||
void uploadRemoveRequested(TransferData * transfer); | |||
void uploadRestartRequested(TransferData * transfer); | |||
void downloadRemoveRequested(TransferData * transfer); | |||
void destinationDirChanged(QString & value); | |||
void setupConnectionRequested(bool server, quint16 port, QString & host); | |||
private: | |||
CConnectionDialog * m_ConnectionDialog; | |||
QAction * m_FileOpen; | |||
QAction * m_ConnectionAsServer; | |||
QAction * m_ConnectionAsClient; | |||
QAction * m_ConnectionDisconnect; | |||
QAction * m_TransferRestartAction; | |||
QAction * m_TransferCancelAction; | |||
bool m_ActAsServer; | |||
bool m_Connected; | |||
QString m_DestinationDir; | |||
QTransferDataList m_Data; | |||
CTransferThread * m_TransferThread; | |||
QListView * m_TransferView; | |||
TransferData * m_SelectedTransfer; | |||
void setupUi(); | |||
void removeFileTransfer(TransferData * transfer); | |||
void cleanup(); | |||
inline void createThread(); | |||
private slots: | |||
void setupConnection(); | |||
void connectToWorker(CWorker * worker); | |||
void updateConnectionState(bool connected); | |||
void handleSelectionChanged(const QItemSelection & selected); | |||
void addTransfer(TransferData * transfer); | |||
void removeTransfer(TransferData * transfer); | |||
void updateStatusBar(const QString & message); | |||
void about(); | |||
}; | |||
} | |||
#endif |
@ -0,0 +1,75 @@ | |||
/*************************************************************************** | |||
* Copyright (C) 2008 by Oliver Groß * | |||
* z.o.gross@gmx.de * | |||
* * | |||
* This program is free software; you can redistribute it and/or modify * | |||
* it under the terms of the GNU General Public License as published by * | |||
* the Free Software Foundation; either version 2 of the License, or * | |||
* (at your option) any later version. * | |||
* * | |||
* This program is distributed in the hope that it will be useful, * | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||
* GNU General Public License for more details. * | |||
* * | |||
* You should have received a copy of the GNU General Public License * | |||
* along with this program; if not, write to the * | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#include "ctransferthread.h" | |||
#include "csocketmanager.h" | |||
#include <QTcpServer> | |||
namespace qftrans { | |||
CTransferThread::CTransferThread(QObject * parent) : QThread(parent), | |||
m_SocketManager(NULL) { | |||
} | |||
CTransferThread::~CTransferThread() { | |||
if (m_SocketManager) | |||
m_SocketManager->deleteLater(); | |||
/* if (m_Socket) | |||
delete m_Socket; | |||
if (m_Worker) | |||
delete m_Worker; | |||
if (m_Server) | |||
delete m_Server;*/ | |||
} | |||
void CTransferThread::run() { | |||
qDebug() << "start transfer thread" << currentThreadId(); | |||
m_SocketManager = new CSocketManager(); | |||
emit socketManagerReady(); | |||
exec(); | |||
qDebug() << "exit transfer thread" << currentThreadId(); | |||
if (m_SocketManager) { | |||
delete m_SocketManager; | |||
// m_SocketManager->deleteLater(); | |||
m_SocketManager = NULL; | |||
} | |||
/* if (m_Worker) { | |||
delete m_Worker; | |||
m_Worker = NULL; | |||
} | |||
if (m_Server) { | |||
delete m_Server; | |||
m_Server = NULL; | |||
} | |||
if (m_Socket) { | |||
delete m_Socket; | |||
m_Socket = NULL; | |||
}*/ | |||
// emit connectionChanged(false); | |||
} | |||
} |
@ -0,0 +1,50 @@ | |||
/*************************************************************************** | |||
* Copyright (C) 2008 by Oliver Groß * | |||
* z.o.gross@gmx.de * | |||
* * | |||
* This program is free software; you can redistribute it and/or modify * | |||
* it under the terms of the GNU General Public License as published by * | |||
* the Free Software Foundation; either version 2 of the License, or * | |||
* (at your option) any later version. * | |||
* * | |||
* This program is distributed in the hope that it will be useful, * | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||
* GNU General Public License for more details. * | |||
* * | |||
* You should have received a copy of the GNU General Public License * | |||
* along with this program; if not, write to the * | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef QFTRANS_CTRANSFERTHREAD_H | |||
#define QFTRANS_CTRANSFERTHREAD_H | |||
#include <QThread> | |||
#include "common.h" | |||
namespace qftrans { | |||
class CSocketManager; | |||
/** | |||
@author Oliver Groß <z.o.gross@gmx.de> | |||
*/ | |||
class CTransferThread : public QThread { | |||
Q_OBJECT | |||
public: | |||
CTransferThread(QObject * parent = 0); | |||
~CTransferThread(); | |||
// CWorker * worker() { return m_Worker; } | |||
CSocketManager * socketManager() { return m_SocketManager; } | |||
signals: | |||
void socketManagerReady(); | |||
protected: | |||
CSocketManager * m_SocketManager; | |||
void run(); | |||
}; | |||
} | |||
#endif |
@ -0,0 +1,425 @@ | |||
/*************************************************************************** | |||
* Copyright (C) 2008 by Oliver Groß * | |||
* z.o.gross@gmx.de * | |||
* * | |||
* This program is free software; you can redistribute it and/or modify * | |||
* it under the terms of the GNU General Public License as published by * | |||
* the Free Software Foundation; either version 2 of the License, or * | |||
* (at your option) any later version. * | |||
* * | |||
* This program is distributed in the hope that it will be useful, * | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |||
* GNU General Public License for more details. * | |||
* * | |||
* You should have received a copy of the GNU General Public License * | |||
* along with this program; if not, write to the * | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#include "cworker.h" | |||
#include <QTcpSocket> | |||
#include <QByteArray> | |||
#include <QFile> | |||
#include <QDir> | |||
#include <QThread> | |||
namespace qftrans { | |||
CWorker::CWorker(QTcpSocket * socket, QObject * parent) : QObject(parent), m_Socket(socket), m_IdCounter(0) { | |||
connect(m_Socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error(QAbstractSocket::SocketError))); | |||
connect(m_Socket, SIGNAL(bytesWritten(qint64)), this, SLOT(writeData()), Qt::QueuedConnection); | |||
connect(m_Socket, SIGNAL(readyRead()), this, SLOT(readData()), Qt::QueuedConnection); | |||
qDebug() << "worker created"; | |||
} | |||
CWorker::~CWorker() { | |||
qDebug() << "worker removed"; | |||
} | |||
//TODO addUpload | |||
void CWorker::addUpload(TransferData * transfer) { | |||
if (!m_UploadDict.contains(transfer)) { | |||
qDebug() << "adding upload"; | |||
transfer->status = TS_WAITING; | |||
m_UploadDict.insert(transfer, m_IdCounter); | |||
m_IdCounter++; | |||
} | |||
} | |||
//TODO removeUpload | |||
void CWorker::removeUpload(TransferData * transfer) { | |||
if (m_UploadDict.contains(transfer) && transfer->status != TS_WAITING) { | |||
transfer->status = TS_CLOSING; | |||
if (m_Socket->bytesToWrite() == 0) { | |||
qDebug() << "executing upload"; | |||
writeData(); | |||
} | |||
} | |||
} | |||
//TODO startUpload | |||
void CWorker::startUpload(TransferData * transfer) { | |||
if (m_UploadDict.contains(transfer) && transfer->status == TS_WAITING) { | |||
qDebug() << "scheduling upload for announce"; | |||
transfer->status = TS_ANNOUNCING; | |||
if (m_Socket->bytesToWrite() == 0) { | |||
qDebug() << "executing upload"; | |||
writeData(); | |||
} | |||
} | |||
} | |||
void CWorker::startUploadData(quint32 id) { | |||
TransferData * transfer = m_UploadDict.key(id); | |||
if (transfer) { | |||
qDebug() << "scheduling upload for transfer"; | |||
transfer->status = TS_TRANSFERING; | |||
if (m_Socket->bytesToWrite() == 0) { | |||
qDebug() << "executing upload"; | |||
writeData(); | |||
} | |||
} | |||
} | |||
void CWorker::sendAcknowledge(quint32 id) { | |||
QByteArray block; | |||
QDataStream out(&block, QIODevice::WriteOnly); | |||
out.setVersion(QDataStream::Qt_4_0); | |||
TransferHeader header; | |||
// header.descriptor = DESCRIPTOR_STRING; | |||
header.type = HT_ACK; | |||
header.id = id; | |||
header.length = 0; | |||
out.writeRawData((const char *)(&header), sizeof(TransferHeader)); | |||
< |