00001 #include <QtNetwork>
00002 #include <QFileInfo>
00003 #include <QMessageBox>
00004 #include "exeptions.h"
00005
00006
00007 #include "fileTransfer.h"
00008 #include "math.h"
00009
00010
00011 #define BUF_SIZE 10240
00012
00013 SendFileThread::SendFileThread(QObject *parent, const QString &path, const QHostAddress &ip, quint16 port) : QThread (parent)
00014 {
00015 this->path = path;
00016 this->ip = ip;
00017 this->port = port;
00018 cancel_transfer = false;
00019 }
00020
00021 void SendFileThread::cancelTransfer ()
00022 {
00023 cancel_transfer = true;
00024 }
00025
00026 void SendFileThread::run ()
00027 {
00028 QTcpSocket send_socket (this);
00029 send_socket.connectToHost (ip, port, QIODevice::WriteOnly);
00030 if (!send_socket.waitForConnected(2000))
00031 {
00032 qDebug ("nie mozna sie polaczyc z %s:%d", ip.toString().toAscii().data(), port);
00033 emit transferEnd (false);
00034 return;
00035 }
00036 QFile plik(path);
00037 QFileInfo info(path);
00038 qint64 size = info.size ();
00039 qint64 sent_count=0;
00040 if(plik.open(QIODevice::ReadOnly) == true)
00041 {
00042 QByteArray dane = plik.read (BUF_SIZE);
00043
00044 while (!dane.isEmpty ())
00045 {
00046 if (cancel_transfer)
00047 {
00048 send_socket.close ();
00049 plik.close ();
00050 send_socket.waitForDisconnected (5000);
00051
00052 return;
00053 }
00054 send_socket.waitForBytesWritten (5000);
00055 qint64 tmp = send_socket.write (dane);
00056 if (tmp == -1)
00057 {
00058 qDebug ("Nastapil blad wysylania danych %d", send_socket.error());
00059 send_socket.close ();
00060 emit transferEnd (false);
00061 return;
00062 }
00063 sent_count += tmp;
00064 if (send_socket.state () != QAbstractSocket::ConnectedState && sent_count != size)
00065 {
00066 qDebug ("Blad wysylania danych, prawdopodobnie odbiorca anulowal odbieranie %d", send_socket.error ());
00067 send_socket.close ();
00068 emit transferEnd (false);
00069 return;
00070 }
00071 int transfer_progres = floor(100.0*((double)sent_count / (double)size));
00072
00073
00074 emit transferProgres (transfer_progres);
00075 dane = plik.read (BUF_SIZE);
00076 }
00077 send_socket.close ();
00078 send_socket.waitForDisconnected (30000);
00079 emit transferEnd(true);
00080 }
00081 else
00082 {
00083 qDebug ("Bład, nie mogę czytać pliku");
00084 send_socket.close ();
00085 send_socket.waitForDisconnected (30000);
00086 emit transferEnd(false);
00087 }
00088 }
00089
00090 FileTransfer::FileTransfer() : QObject()
00091 {
00092 receive_file_socket = NULL;
00093 out_file = NULL;
00094 send_file_thread = NULL;
00095 }
00096
00097 FileTransfer::~FileTransfer()
00098 {
00099 if (send_file_thread)
00100 {
00101 send_file_thread->cancelTransfer ();
00102 send_file_thread->wait (10000);
00103 delete send_file_thread;
00104 }
00105
00106 delete out_file;
00107 }
00108
00109 void FileTransfer::receiveFile()
00110 {
00111 qint64 read_size = receive_file_socket->bytesAvailable();
00112 QByteArray dane = receive_file_socket->read (read_size);
00113 transfer_bytes += read_size;
00114
00115 if (out_file->isWritable())
00116 out_file->write (dane);
00117 else
00118 qDebug ("Nie moge zapisywac do pliku");
00119
00120
00121
00122 int transfer_progres = floor (100.0*((double)transfer_bytes / (double)file_size));
00123 emit posOfProgresBarChanged(transfer_progres);
00124
00125 if (transfer_bytes >= file_size)
00126 {
00127 out_file->close ();
00128 delete out_file;
00129 out_file = NULL;
00130 receive_file_socket->waitForDisconnected (30000);
00131 if (transfer_bytes > file_size)
00132 {
00133 qDebug ("przyslano za duzy plik");
00134 emit transferEnd (false);
00135 }
00136 else
00137 emit transferEnd (true);
00138 }
00139 }
00140
00141 void FileTransfer::sendFile (const QHostAddress &ip, quint16 port, const QString &path)
00142 {
00143 this->ip = ip;
00144 send_file_thread = new SendFileThread (this, path, ip, port);
00145 connect (send_file_thread, SIGNAL(transferProgres(int)), this, SLOT(threadTransferProgres(int)));
00146 connect (send_file_thread, SIGNAL(transferEnd(bool)), this, SLOT(threadTransferEnd(bool)));
00147 send_file_thread->start ();
00148 }
00149
00150 void FileTransfer::cancelTransfer()
00151 {
00152
00153 receive_file_server.close ();
00154 delete out_file;
00155 if (send_file_thread)
00156 {
00157 send_file_thread->cancelTransfer ();
00158 send_file_thread->wait (10000);
00159 delete send_file_thread;
00160 send_file_thread = NULL;
00161 }
00162 out_file = NULL;
00163 }
00164
00165 void FileTransfer::receiveFile (const QHostAddress &ip, quint16 port, const QString &path, qint64 file_size)
00166 {
00167 out_file = new QFile (path);
00168 out_file->open(QIODevice::WriteOnly);
00169 if (!out_file->isWritable ())
00170 {
00171 qDebug ("Nie mogę zapisywać do %s", path.toAscii().data());
00172 delete out_file;
00173 out_file = NULL;
00174 throw Exeptions (1, QObject::tr("Nie można zapisywać do pliku"), QObject::tr("Communication::receiveFile"), QObject::tr("Nie można zapisywać do pliku ")+path+tr(" Prawdopodobnie plik nie ma uprawnień zapisu"));
00175 }
00176
00177 this->ip = ip;
00178 this->file_size = file_size;
00179
00180 connect (&receive_file_server, SIGNAL(newConnection()), this, SLOT(newConnection()));
00181 if (!receive_file_server.listen (QHostAddress::Any, port))
00182 {
00183 receive_file_server.close ();
00184 qDebug ("Nie można nasłuchiwać na porcie %d", port);
00185 throw Exeptions (1, QObject::tr("Nie można nasłuchiwać"), QObject::tr("Communication::receiveFile"), QObject::tr("Nie można nasłuchiwać na porcie ")+QString::number (port)+tr(" Prawdopodobnie port jest zajęty lub nie mamy do niego dostępu"));
00186 }
00187 }
00188
00189 QHostAddress FileTransfer::getIp()
00190 {
00191 return ip;
00192 }
00193
00194
00195 void FileTransfer::newConnection ()
00196 {
00197 receive_file_socket = receive_file_server.nextPendingConnection ();
00198
00199 if (!(ip == receive_file_socket->peerAddress()))
00200 {
00201 qDebug ("Proba wyslania pliku od nieznajomego");
00202 receive_file_socket->abort ();
00203 receive_file_socket->deleteLater ();
00204 receive_file_socket = NULL;
00205 }
00206 else
00207 {
00208 qDebug ("Otrzymalem polaczenie od %s", receive_file_socket->peerAddress().toString().toAscii().data());
00209 transfer_bytes = 0;
00210
00211 connect (receive_file_socket, SIGNAL(readyRead()), this, SLOT(receiveFile()));
00212 connect (receive_file_socket, SIGNAL(error (QAbstractSocket::SocketError)), this, SLOT(receiveSocketError(QAbstractSocket::SocketError)));
00213 receive_file_server.close ();
00214 }
00215 }
00216
00217 void FileTransfer::receiveSocketError (QAbstractSocket::SocketError error)
00218 {
00219 if (file_size != transfer_bytes)
00220 {
00221 qDebug ("Użytkownik niespodziewanie rozłączył się %d", error);
00222 receive_file_socket->close ();
00223 receive_file_socket->setParent (0);
00224
00225 receive_file_socket = NULL;
00226 emit transferEnd (false);
00227 }
00228 }
00229
00230 void FileTransfer::threadTransferProgres (int perc)
00231 {
00232
00233 emit posOfProgresBarChanged (perc);
00234 }
00235
00236 void FileTransfer::threadTransferEnd (bool ok)
00237 {
00238 emit transferEnd (ok);
00239 }
00240