communication.cpp

Idź do dokumentacji tego pliku.
00001 #include <QByteArray>
00002 #include <string.h>
00003 
00004 #include "exeptions.h"
00005 #include "communication.h"
00006 #include <MD5Hash.h>
00007 #include <QFileInfo>
00008 #include <stdlib.h>
00009 
00010 
00011 
00012 //#define MAIN_PORT             2310
00013 #define PACKET_TIME     10000
00014 #define PACKET_RETRY    3
00015 #define PING_TIME               60000
00016 #define CONNECT_TIMEOUT 5000
00017 #define FILE_PORT       2330
00018 
00019 #define MAX_PING_TIME   5000
00020 #define MAX_FILE_TIME   120000
00021 
00022 
00023 uint qHash (const QHostAddress &ip)
00024 {
00025         return ip.toIPv4Address ();
00026 }
00027 
00028 LanPacket::LanPacket ()
00029 {
00030         clearData ();
00031 }
00032 
00033 LanPacket::LanPacket (const QByteArray &data)
00034 {
00035         clearData ();
00036         if (data.size () < 3 || data.at(0) <= Invalid ||  data.at(0) > FileRefuse)
00037         {
00038                 qDebug ("LanPacket::LanPacket(QByteArray) :: nieprawidlowy pakiet\n");
00039                 return;
00040         }
00041 
00042         packet_type = (PacketType) data.at(0);
00043         data_size = (quint8)data.at(1) | (quint8)data.at(2) << 8;
00044         if (data.size() < data_size+3)
00045         {
00046                 qDebug ("LanPacket::LanPacket(QByteArray) :: nieprawidlowy pakiet - za krotki\n");
00047                 return;
00048         }
00049 
00050         switch (packet_type)
00051         {
00052                 case Welcome:
00053                         file_size = (quint8)data.at(3) | (quint8)data.at(4) << 8 | (quint8)data.at(5) << 16 | (quint8)data.at(6) << 24;
00054                         str_data = QString::fromUtf8(data.mid(7, data_size-4).data(), data_size-4);
00055                         if (str_data.size () < 1)
00056                         {
00057                                 qDebug ("LanPacket::LanPacket(QByteArray) :: pakiet welcome nie zawiera nicka\n");
00058                                 return;
00059                         }
00060                         is_valid = true;
00061                 break;
00062 
00063                 case Hi:
00064                         str_data = QString::fromUtf8(data.mid(3, data_size).data(), data_size);
00065                         if (str_data.size () < 1)
00066                         {
00067                                 qDebug ("LanPacket::LanPacket(QByteArray) :: pakiet hi nie zawiera nicka\n");
00068                                 return;
00069                         }
00070                         is_valid = true;
00071                 break;
00072 
00073                 case Bye:
00074                 case Ping:
00075                 case Pong:
00076                 case SysPing:
00077                 case SysPong:
00078                         is_valid = true;
00079                 break;
00080 
00081                 case Bmsg:
00082                         str_data = QString::fromUtf8(data.mid(3, data_size).data(), data_size);
00083                         if (str_data.size () < 1)
00084                         {
00085                                 qDebug ("LanPacket::LanPacket(QByteArray) :: akiet broadcast msg nie zawiera tresci\n");
00086                                 return;
00087                         }
00088                         is_valid = true;
00089                 break;
00090                                 qDebug ("LanPacket::LanPacket(QByteArray) :: \n");
00091 
00092                 case BmsgOk:
00093                         str_data = QString::fromUtf8(data.mid(3, data_size).data(), data_size);
00094                         if (str_data.size () < 1)
00095                         {
00096                                 qDebug ("LanPacket::LanPacket(QByteArray) :: Pakiet broadcast msg ok nie zawiera md5\n");
00097                                 return;
00098                         }
00099                         is_valid = true;
00100                 break;
00101 
00102                 case Pmsg:
00103                         str_data = QString::fromUtf8(data.mid(3, data_size).data(), data_size);
00104                         if (str_data.size () < 1)
00105                         {
00106                                 qDebug ("LanPacket::LanPacket(QByteArray) :: Pakiet private msg nie zawiera tresci\n");
00107                                 return;
00108                         }
00109                         is_valid = true;
00110                 break;
00111 
00112                 case PmsgOk:
00113                         str_data = QString::fromUtf8(data.mid(3, data_size).data(), data_size);
00114                         if (str_data.size () < 1)
00115                         {
00116                                 qDebug ("LanPacket::LanPacket(QByteArray) :: Pakiet private msg ok nie zawiera md5\n");
00117                                 return;
00118                         }
00119                         is_valid = true;
00120                 break;
00121 
00122                 case FileReq:
00123                         if (data_size < 5)
00124                         {
00125                                 qDebug ("LanPacket::LanPacket(QByteArray) :: Pakiet file request jest za krótki\n");
00126                                 return;
00127                         }
00128 
00129                         file_size = (quint8)data.at(3) | (quint8)data.at(4) << 8 | (quint8)data.at(5) << 16 | (quint8)data.at(6) << 24;
00130                         str_data = QString::fromUtf8(data.mid(7, data_size-4).data(), data_size-4);
00131                         is_valid = true;
00132                 break;
00133 
00134                 case FileOk:
00135                         if (data_size < 3)
00136                         {
00137                                 qDebug ("LanPacket::LanPacket(QByteArray) :: Pakiet file ok jest za krótki\n");
00138                                 return;
00139                         }
00140 
00141                         port = (quint8)data.at(3) | (quint8)data.at(4) << 8;
00142                         str_data = QString::fromUtf8(data.mid(5, data_size-2).data(), data_size-2);
00143                         is_valid = true;
00144                 break;
00145 
00146                 case FileRefuse:
00147                         str_data = QString::fromUtf8(data.mid(3, data_size).data(), data_size);
00148                         if (str_data.size () < 1)
00149                         {
00150                                 qDebug ("LanPacket::LanPacket(QByteArray) :: Pakiet file refuse nie zawiera md5\n");
00151                                 return;
00152                         }
00153                         is_valid = true;
00154                 break;
00155 
00156                 default:
00157                         is_valid = false;
00158                 break;
00159         }
00160 }
00161 
00162 LanPacket::LanPacket (const enum PacketType packet_type)
00163 {
00164         clearData ();
00165         this->packet_type = packet_type;
00166         is_valid = validate ();
00167 }
00168 
00169 LanPacket::LanPacket (const enum PacketType packet_type, const QString& str_data, quint32 file_size, quint16 port)
00170 {
00171         clearData ();
00172         this->packet_type = packet_type;
00173         this->str_data = QString (str_data);
00174         if (file_size)  this->file_size = file_size;
00175         if (port)       this->port = port;
00176         is_valid = validate ();
00177 }
00178 
00179 bool LanPacket::isValid () const
00180 {
00181         return is_valid;
00182 }
00183 
00184 QByteArray LanPacket::constData ()
00185 {
00186         if (!is_valid)  return QByteArray();
00187         if (!packet_data.isEmpty ())
00188                         return QByteArray (packet_data);
00189 
00190         char tmp_char = packet_type;
00191         packet_data.append (tmp_char);
00192         QByteArray      utf_str;
00193 
00194         switch (packet_type)
00195         {
00196                 case Hi:
00197                 case Bmsg:
00198                 case BmsgOk:
00199                 case Pmsg:
00200                 case PmsgOk:
00201                 case FileRefuse:
00202                         utf_str = str_data.toUtf8 ();
00203                         data_size = utf_str.size ();
00204                         packet_data.append (packInt(data_size, false));
00205                         packet_data.append (utf_str);
00206                 break;
00207 
00208                 case Welcome:
00209                 case FileReq:
00210                         utf_str = str_data.toUtf8 ();
00211                         data_size = utf_str.size ()+4;
00212                         packet_data.append (packInt(data_size, false));
00213                         packet_data.append (packInt(file_size, true));
00214                         packet_data.append (utf_str);
00215                 break;
00216 
00217                 case FileOk:
00218                         utf_str = str_data.toUtf8 ();
00219                         data_size = utf_str.size ()+2;
00220                         packet_data.append (packInt(data_size, false));
00221                         packet_data.append (packInt(port, false));
00222                         packet_data.append (utf_str);
00223                 break;
00224 
00225                 default:
00226                         data_size = 0;
00227                         packet_data.append (packInt(data_size, false));
00228                 break;
00229         }
00230         return QByteArray (packet_data);
00231 }
00232 
00233 LanPacket::PacketType LanPacket::getType () const
00234 {
00235         return packet_type;
00236 }
00237 
00238 quint16 LanPacket::getSize () const
00239 {
00240         return data_size;
00241 }
00242 
00243 QString LanPacket::getString () const
00244 {
00245         return QString (str_data);
00246 }
00247 
00248 quint32 LanPacket::getFileSize () const
00249 {
00250         return file_size;
00251 }
00252 
00253 quint16 LanPacket::getPort () const
00254 {
00255         return port;
00256 }
00257 
00258 QByteArray LanPacket::packInt (quint32 num, bool bit32)
00259 {
00260         char tmp[4];
00261         tmp[0] = num & 0xff;
00262         tmp[1] = (num >> 8) & 0xff;
00263         if (bit32)
00264         {
00265                 tmp[2] = (num >> 16) & 0xff;
00266                 tmp[3] = (num >> 24) & 0xff;
00267         }
00268         return QByteArray (tmp, bit32 ? 4 : 2);
00269 }
00270 
00271 void LanPacket::clearData ()
00272 {
00273         packet_type = Invalid;
00274         is_valid = false;
00275         packet_data.clear ();
00276         str_data.clear ();
00277         data_size = file_size = port = 0;
00278 }
00279 
00280 bool LanPacket::validate ()
00281 {
00282         if (packet_type == Invalid)     return false;
00283 
00284         switch (packet_type)
00285         {
00286                 case Welcome:
00287                 case Hi:
00288                 case Bmsg:
00289                 case BmsgOk:
00290                 case Pmsg:
00291                 case PmsgOk:
00292                 case FileRefuse:
00293                         if (str_data.isEmpty()) return false;
00294                 break;
00295 
00296                 case FileReq:
00297                         if (str_data.isEmpty()) return false;
00298                         if (!file_size) return false;
00299                 break;
00300 
00301                 case FileOk:
00302                         if (str_data.isEmpty()) return false;
00303                         if (!port)      return false;
00304                 break;
00305 
00306                 default:
00307                         return true;
00308                 break;
00309         }
00310         return true;
00311 }
00312 
00313 
00314 
00315 
00316 
00317 
00318 
00319 
00320 /************************ klasa glowna **************************/
00321 
00322 Communication::Communication () : QObject ()
00323 {
00324         QTime time = QTime::currentTime ();
00325 
00326         srand (time.msec ());
00327         rand_num = rand ();
00328         is_connect = connecting = false;
00329         ip_list.clear ();
00330         ping_list.clear ();
00331         packet_queue.clear ();
00332         incoming_file.clear ();
00333         is_transfer = false;
00334         file_transfer = NULL;
00335 
00336         packet_timer = new QTimer (this);
00337         ping_timer = new QTimer (this);
00338         connect_timer = NULL;
00339         connect (packet_timer, SIGNAL(timeout()), this, SLOT(packetTimer()));
00340         connect (ping_timer, SIGNAL(timeout()), this, SLOT(sysPingTimer()));
00341         connect (&read_socket, SIGNAL(readyRead()), this, SLOT(readData()));
00342 
00343         srand (rand_num);
00344         rand_num = rand ();
00345 }
00346 
00347 Communication::~Communication ()
00348 {
00349         delete packet_timer;
00350         delete ping_timer;
00351         delete file_transfer;
00352         if (is_connect) bye ();
00353 }
00354 
00355 void Communication::welcome (const QString& nick, QHostAddress broadcast, quint16 port)
00356 {
00357         if (nick.isEmpty ())
00358                 throw Exeptions (1, QObject::tr("Niedozwolony pusty nick"), QObject::tr("Communication::welcome (QString,QHostAddress,quint16)"), QObject::tr("Próba połączenia z pustym nickiem"));
00359         if (is_connect)
00360                 throw Exeptions (1, QObject::tr("Program jest połączony"), QObject::tr("Communication::welcome (QString,QHostAddress,quint16)"), QObject::tr("Próba ponownego połączenia, gdy program jest już połączony"));
00361         if (connecting)
00362                 throw Exeptions (1, QObject::tr("Program łączy się"), QObject::tr("Communication::welcome (QString,QHostAddress,quint16)"), QObject::tr("Próba połączenia, podczas gdy program jest w trakcie łączenia"));
00363 
00364         this->main_port = port;
00365         this->broadcast = broadcast;
00366         user_nick = nick;
00367         my_ip.clear ();
00368         srand (rand_num);
00369         rand_num = rand ();
00370 
00371         ip_list.clear ();
00372         packet_queue.clear ();
00373         incoming_file.clear ();
00374         connecting = true;
00375         if (!read_socket.bind (main_port))
00376         {
00377                 qDebug ("Nie mozna wywolac bind na porcie %d", main_port);
00378                 read_socket.close ();
00379                 connecting = false;
00380                 throw Exeptions (1, QObject::tr("Nie można nasłuchiwać"), QObject::tr("Communication::welcome (QString,QHostAddress,quint16)"), QObject::tr("Nie można nasłuchiwać na porcie ")+QString::number (main_port)+tr(" Prawdopodobnie port jest zajęty lub nie mamy do niego dostępu"));
00381         }
00382 
00383         connect_timer = new QTimer (this);
00384         connect_timer->setSingleShot (true);
00385         connect_timer->setInterval (CONNECT_TIMEOUT);
00386         connect_timer->start (CONNECT_TIMEOUT);
00387         connect (connect_timer, SIGNAL(timeout()), this, SLOT(connectTimeOut ()));
00388 
00389         ping_list.clear ();
00390         send_file_list.clear ();
00391         is_transfer = false;
00392         delete file_transfer;
00393         file_transfer = NULL;
00394         this->sendPacket (broadcast, LanPacket(LanPacket::Welcome, nick, rand_num));
00395 }
00396 
00397 void Communication::bye ()
00398 {
00399         if (!is_connect && !connecting)
00400                 throw Exeptions (1, QObject::tr("Program rozłączony"), QObject::tr("Communication::bye ()"), QObject::tr("Próba rozłączenia podczas gdy program jest rozłączony"));
00401 
00402         this->sendPacket (broadcast, LanPacket(LanPacket::Bye));
00403         packet_timer->stop ();
00404         ping_timer->stop ();
00405 
00406         user_nick.clear ();
00407         packet_queue.clear ();
00408         ip_list.clear ();
00409         send_file_list.clear ();
00410         incoming_file.clear ();
00411         is_connect = connecting = false;
00412         read_socket.close ();
00413         my_ip.clear ();
00414         if (connect_timer)
00415         {
00416                 disconnect (connect_timer, SIGNAL(timeout()), this, SLOT(connectTimeOut ()));
00417                 delete connect_timer;
00418                 connect_timer = NULL;
00419         }
00420         if (is_transfer)
00421         {
00422                 emit transferEnd (file_transfer->getIp(), false);
00423                 is_transfer = false;
00424                 delete file_transfer;
00425                 file_transfer = NULL;
00426         }
00427 }
00428 
00429 void Communication::sendPMsg (const QHostAddress &user_ip, const QString& msg)
00430 {
00431         checkConnection ("Communication::sendPMsg (const QHostAddress, const QString)");
00432         this->sendPacket (user_ip, LanPacket(LanPacket::Pmsg, msg), true);
00433 }
00434 
00435 void Communication::sendBMsg (const QString& msg)
00436 {
00437         checkConnection ("Communication::sendBMsg (const QString)");
00438         this->sendPacket (broadcast, LanPacket(LanPacket::Bmsg, msg), true);
00439 }
00440 
00441 void Communication::sendFile (QHostAddress user_ip, QString file_name)
00442 {
00443         checkConnection ("Communication::sendFile (QHostAddress, QString, quint32)");
00444         if (is_transfer)
00445                 throw Exeptions (1, tr("Można wysłać tylko jeden plik"), tr("Communication::sendFile (QHostAddress, QString, quint32)"), tr("Próba wysłania pliku podczas gdy plik jest przesyłany"));
00446 
00447         QFileInfo file_info (file_name);
00448         quint32 file_size = file_info.size ();
00449         SendFileTime sft;
00450         sft.name = file_name;
00451         sft.time = QTime::currentTime ();
00452         sft.time.start ();
00453         send_file_list.insert (user_ip, sft);
00454         this->sendPacket (user_ip, LanPacket(LanPacket::FileReq, file_info.fileName(), file_size));
00455 }
00456 
00457 void Communication::checkPing (QHostAddress user_ip)
00458 {
00459         checkConnection ("Communication::checkPing (QHostAddress)");
00460 
00461         if (ping_list.contains (user_ip))
00462                 return;
00463         this->sendPacket (user_ip, LanPacket(LanPacket::Ping));
00464         ping_list.insert (user_ip, QTime::currentTime());
00465         ping_list[user_ip].start();
00466 }
00467 
00468 void Communication::acceptFileRequest (QHostAddress user_ip, const QString &path)
00469 {
00470         checkConnection ("Communication::acceptFileRequest (QHostAddress, quint16)");
00471 
00472         if (!incoming_file.contains (user_ip))
00473                 throw Exeptions(1, QObject::tr("Brak żądania wysłania pliku"), QObject::tr("Communication::refuseFileRequest (QHostAddress)"), QObject::tr("Próba przyjęcia pliku od użytkownika który nie wysyłał żądania"));
00474 
00475         is_transfer = true;
00476         file_transfer = new FileTransfer ();
00477         connect (file_transfer, SIGNAL(transferEnd(bool)), this, SLOT(fileTransferEnd(bool)));  //koniec transferu
00478         connect (file_transfer, SIGNAL(posOfProgresBarChanged(int)), this, SLOT(fileTransferProgres(int)));     //postep
00479 
00480         try
00481         {
00482                 file_transfer->receiveFile (user_ip, FILE_PORT, path, incoming_file.value(user_ip).size);
00483         }
00484         catch (Exeptions & wyjatek)
00485         {
00486                 this->sendPacket (user_ip, LanPacket(LanPacket::FileRefuse, MD5Hash::hashData(incoming_file.value(user_ip).name.toUtf8())));
00487                 throw wyjatek;
00488         }
00489 
00490         this->sendPacket (user_ip, LanPacket(LanPacket::FileOk, MD5Hash::hashData(incoming_file.value(user_ip).name.toUtf8()), (quint32) 0, (quint16) FILE_PORT));
00491 
00492         incoming_file.remove (user_ip);
00493 }
00494 
00495 void Communication::refuseFileRequest (QHostAddress user_ip)
00496 {
00497         checkConnection ("Communication::refuseFileRequest (QHostAddress)");
00498 
00499         if (!incoming_file.contains (user_ip))
00500                 throw Exeptions(1, QObject::tr("Brak żądania wysłania pliku"), QObject::tr("Communication::refuseFileRequest (QHostAddress)"), QObject::tr("Próba odmówienia przyjęcia pliku od użytkownika który nie wysyłał żądania"));
00501 
00502         this->sendPacket (user_ip, LanPacket(LanPacket::FileRefuse, MD5Hash::hashData(incoming_file.value(user_ip).name.toUtf8())));
00503         incoming_file.remove (user_ip);
00504 }
00505 
00506 void Communication::cancelTranfer ()
00507 {
00508         if (!is_transfer)
00509                 return;
00510         is_transfer = false;
00511         file_transfer->cancelTransfer ();
00512         file_transfer->deleteLater ();
00513 //      delete file_transfer;
00514         file_transfer = NULL;
00515 }
00516 
00517 
00518 
00519 
00520 
00521 /* metody prywatne **************************/
00522 
00523 void Communication::connectOk (const QHostAddress &ip)
00524 {
00525         if (connect_timer)
00526         {
00527                 disconnect (connect_timer, SIGNAL(timeout()), this, SLOT(connectTimeOut ()));
00528                 delete connect_timer;
00529                 connect_timer = NULL;
00530         }
00531         my_ip = ip;
00532         packet_timer->start (PACKET_TIME);
00533         ping_timer->start (PING_TIME);
00534         connecting = false;
00535         is_connect = true;
00536         emit connected ();
00537         qDebug ("polaczony\n");
00538 }
00539 
00540 void Communication::connectFail ()
00541 {
00542         this->bye ();
00543         emit unableConnect ();
00544         qDebug ("nie mozna polaczyc\n");
00545 
00546 }
00547 
00548 void Communication::checkConnection (const QString &place)
00549 {
00550         if (!is_connect)
00551                 throw Exeptions(1, tr("Niepołączony"), place, tr("Próba wysłania pakietu gdy program jest niepołączony"));
00552 }
00553 
00554 void Communication::sendPacket (QHostAddress ip, LanPacket packet, bool control)
00555 {
00556         QUdpSocket      socket (this);
00557         if (!packet.isValid ())
00558         {
00559                 qDebug ("Próba wysłania nieprawidłowego pakietu\n");
00560                 return;
00561         }
00562         if (!is_connect && packet.getType () != LanPacket::Welcome)
00563                 return;
00564 
00565         socket.writeDatagram (packet.constData(), ip, main_port);
00566         socket.flush ();
00567         qDebug ("wyslalem: %d\n", packet.constData().size());
00568 
00569         if (control)
00570         {
00571                 QueueItem qi;
00572                 qi.packet = packet;
00573                 qi.last_send = QTime::currentTime ();
00574                 if (packet.getType() == LanPacket::Pmsg || packet.getType() == LanPacket::Bmsg)
00575                         qi.md5 = MD5Hash::hashData (packet.getString().toUtf8());
00576 
00577                 if (ip == broadcast)
00578                 {
00579                         for (int i=0; i < ip_list.size(); i++)
00580                                 qi.num_err.insert (ip_list.at(i), 0);
00581                 }
00582                 else
00583                         qi.num_err.insert (ip, 0);
00584 
00585                 packet_queue.append (qi);
00586         }
00587 
00588         qDebug ("Wysylam pakiet %d do %s\n", packet.getType(), ip.toString().toAscii().data());
00589 }
00590 
00591 void Communication::servicePacket (LanPacket &packet, QHostAddress ip)
00592 {
00593         QString tmp_str;
00594         LanPacket       res_pack;
00595 
00596         qDebug ("Obsluguje pakiet %d od %s\n", packet.getType(), ip.toString().toAscii().data());
00597 
00598         switch (packet.getType ())
00599         {
00600                 case LanPacket::Welcome:
00601                         if (connecting && packet.getFileSize () == rand_num && packet.getString() == user_nick)
00602                                 connectOk (ip);
00603                         else if (!ip_list.contains (ip))
00604                         {
00605                                 ip_list.append (ip);
00606                                 emit newUser (ip, packet.getString());
00607                         }
00608                         sendPacket (ip, LanPacket(LanPacket::Hi, user_nick));
00609                 break;
00610 
00611                 case LanPacket::Hi:
00612                         if (!ip_list.contains (ip))
00613                         {
00614                                 ip_list.append (ip);
00615                                 if (user_nick == packet.getString ())
00616                                 {
00617                                         this->bye ();
00618                                         qDebug ("Nick jest zajęty, rozlaczam sie");
00619                                         emit invalidNick ();
00620                                 }
00621                                 emit newUser (ip, packet.getString());
00622                         }
00623                 break;
00624 
00625                 case LanPacket::Bye:
00626                         if (ip_list.contains (ip))
00627                                 emit leaveUser (ip);
00628                         removeUser (ip);
00629                 break;
00630 
00631                 case LanPacket::Ping:
00632                         sendPacket (ip, LanPacket(LanPacket::Pong));
00633                 break;
00634 
00635                 case LanPacket::Pong:
00636                         if (ip_list.contains (ip) && ping_list.contains (ip))
00637                         {
00638                                 emit pong (ip, ping_list.value(ip).elapsed());
00639                                 ping_list.remove (ip);
00640                         }
00641                 break;
00642 
00643                 case LanPacket::SysPing:
00644                         sendPacket (ip, LanPacket(LanPacket::SysPong));
00645                 break;
00646 
00647                 case LanPacket::SysPong:
00648                         removeQueue (ip, LanPacket::SysPing, QString());
00649                 break;
00650 
00651                 case LanPacket::Bmsg:
00652                         if (ip_list.contains (ip))
00653                         {
00654                                 emit recvBMsg (ip, packet.getString());
00655                                 tmp_str = MD5Hash::hashData (packet.getString().toUtf8());
00656                                 sendPacket (ip, LanPacket(LanPacket::BmsgOk, tmp_str));
00657                         }
00658                 break;
00659 
00660                 case LanPacket::BmsgOk:
00661                         removeQueue (ip, LanPacket::Bmsg, packet.getString ());
00662                 break;
00663 
00664                 case LanPacket::Pmsg:
00665                         if (ip_list.contains (ip))
00666                         {
00667                                 emit recvPMsg (ip, packet.getString());
00668                                 tmp_str = MD5Hash::hashData (packet.getString().toUtf8());
00669                                 sendPacket (ip, LanPacket(LanPacket::PmsgOk, tmp_str));
00670                         }
00671                 break;
00672 
00673                 case LanPacket::PmsgOk:
00674                                 removeQueue (ip, LanPacket::Pmsg, packet.getString ());
00675                 break;
00676 
00677                 case LanPacket::FileReq:
00678                         if (ip_list.contains (ip))
00679                         {
00680                                 if (is_transfer)
00681                                 {
00682                                         this->sendPacket (ip, LanPacket(LanPacket::FileRefuse, MD5Hash::hashData(packet.getString().toUtf8())));
00683                                 }
00684                                 else
00685                                 {
00686                                         RecvFileSize rfs;
00687                                         rfs.name = packet.getString();
00688                                         rfs.size = packet.getFileSize ();
00689                                         incoming_file.insert (ip, rfs);
00690                                         emit fileRequest (ip, packet.getString(), packet.getFileSize());
00691                                 }
00692                         }
00693                 break;
00694 
00695                 case LanPacket::FileOk:
00696                         if (ip_list.contains(ip) && send_file_list.contains(ip))
00697                         {
00698                                 emit acceptSendFile (ip, send_file_list.value(ip).name);
00699                                 is_transfer = true;
00700 
00701                                 file_transfer = new FileTransfer ();
00702                                 connect (file_transfer, SIGNAL(transferEnd(bool)), this, SLOT(fileTransferEnd(bool)));  //koniec transferu
00703                                 connect (file_transfer, SIGNAL(posOfProgresBarChanged(int)), this, SLOT(fileTransferProgres(int)));     //postep
00704 
00705                                 file_transfer->sendFile (ip, packet.getPort (), send_file_list.value(ip).name);
00706 
00707                                 send_file_list.remove (ip);
00708                         }
00709                 break;
00710 
00711                 case LanPacket::FileRefuse:
00712                         if (ip_list.contains(ip) && send_file_list.contains(ip))
00713                         {
00714                                 emit refuseSendFile (ip, send_file_list.value(ip).name);
00715                                 send_file_list.remove (ip);
00716                         }
00717                 break;
00718 
00719                 default:
00720                         qDebug ("Nieznany pakiet: %d\n", packet.getType());
00721                 break;
00722         }
00723 }
00724 
00725 void Communication::removeUser (QHostAddress user_ip)
00726 {
00727         ip_list.removeAll (user_ip);
00728         if (send_file_list.contains(user_ip))
00729         {
00730                 emit refuseSendFile (user_ip, send_file_list.value(user_ip).name);
00731                 send_file_list.remove (user_ip);
00732         }
00733         if (ping_list.contains(user_ip))
00734         {
00735                 emit pong (user_ip, -1);
00736                 ping_list.remove (user_ip);
00737         }
00738 
00739         for (int i=0; i < packet_queue.size (); i++)
00740         {
00741                 packet_queue[i].num_err.remove (user_ip);
00742                 if (packet_queue.at(i).num_err.isEmpty ())
00743                         packet_queue.removeAt (i);
00744         }
00745         incoming_file.remove (user_ip);
00746 }
00747 
00748 void Communication::removeQueue (QHostAddress user_ip, LanPacket::PacketType pack_type, QString md5)
00749 {
00750         for (int i=0; i < packet_queue.size(); i++)
00751         {
00752                 if (packet_queue[i].packet.getType () != pack_type)
00753                         continue;
00754                 if (!packet_queue.at(i).num_err.contains (user_ip))
00755                         continue;
00756                 if (!md5.isEmpty () && packet_queue.at(i).md5 != md5)
00757                         continue;
00758 
00759                 packet_queue[i].num_err.remove (user_ip);
00760                 if (packet_queue.at(i).num_err.isEmpty())
00761                         packet_queue.removeAt (i);
00762         }
00763 }
00764 
00765 /******* sloty **************/
00766 
00767 void Communication::readData ()
00768 {
00769         if (!is_connect && !connecting)
00770         {
00771                 read_socket.readDatagram (NULL, 0);
00772                 return;
00773         }
00774 
00775         while (read_socket.hasPendingDatagrams ())
00776         {
00777                 QByteArray datagram;
00778                 QHostAddress    user_ip;
00779 
00780                 datagram.resize(read_socket.pendingDatagramSize());
00781                 read_socket.readDatagram(datagram.data(), datagram.size(), &user_ip);
00782 
00783     qDebug ("Przylazl pakiet od %s, %d\n", user_ip.toString().toAscii().data(), datagram.size ());
00784     if (!my_ip.isNull () && user_ip == my_ip)
00785         continue;
00786 
00787                 while (datagram.size () >= 3)
00788                 {
00789                         LanPacket packet (datagram);
00790 
00791                         if (packet.isValid ())
00792                                 servicePacket (packet, user_ip);
00793                         else
00794                                 qDebug ("Nieprawidłowy pakiet !!!!!\n");
00795 
00796                         datagram.remove (0, packet.getSize()+3);
00797                 }
00798         }
00799 }
00800 
00801 void Communication::packetTimer ()
00802 {
00803         QTime time = QTime::currentTime ();
00804         QList<QHostAddress> del_list;
00805 
00806         QHashIterator<QHostAddress, QTime> it_p(ping_list);
00807         while (it_p.hasNext ())
00808         {
00809                 it_p.next ();
00810                 if (it_p.value ().elapsed() > MAX_PING_TIME)
00811                 {
00812                         emit pong (it_p.key(), -1);
00813                         ping_list.remove (it_p.key ());
00814                 }
00815         }
00816 
00817         QHashIterator<QHostAddress, SendFileTime> it_f(send_file_list);
00818         while (it_f.hasNext ())
00819         {
00820                 it_f.next ();
00821                 if (it_f.value().time.elapsed() > MAX_FILE_TIME)
00822                 {
00823                         emit refuseSendFile (it_f.key(), it_f.value().name);
00824                         send_file_list.remove (it_f.key());
00825                 }
00826         }
00827 
00828         for (int i=0; i < packet_queue.size(); i++)
00829         {
00830                 if (packet_queue.at(i).last_send.msecsTo(time) <= PACKET_TIME)
00831                         continue;
00832 
00833                 QHashIterator<QHostAddress, int> it_q(packet_queue.at(i).num_err);
00834                 while (it_q.hasNext ())
00835                 {
00836                         it_q.next ();
00837                         if (it_q.value() > PACKET_RETRY)
00838                         {
00839                                 del_list.append (it_q.key ());
00840                         }
00841                         else
00842                         {
00843                                 packet_queue[i].num_err[it_q.key()]++;
00844                                 sendPacket (it_q.key(), packet_queue.at(i).packet);
00845                         }
00846                 }
00847         }
00848         for (int i=0; i < del_list.size(); i++)
00849         {
00850                 emit leaveUser (del_list.at(i));
00851                 removeUser (del_list.at(i));
00852         }
00853 }
00854 
00855 void Communication::sysPingTimer ()
00856 {
00857         this->sendPacket (broadcast, LanPacket(LanPacket::SysPing), true);
00858 }
00859 
00860 void Communication::connectTimeOut ()
00861 {
00862         if (!is_connect)
00863                 connectFail ();
00864 }
00865 
00866 void Communication::fileTransferEnd (bool ok)
00867 {
00868         is_transfer = false;
00869         emit transferEnd (file_transfer->getIp (), ok);
00870         delete file_transfer;
00871         file_transfer = NULL;
00872 }
00873 
00874 void Communication::fileTransferProgres (int perc)
00875 {
00876         emit fileProgress (perc);
00877 }
00878 

Wygenerowano Sun Jun 11 12:55:08 2006 dla lanChat programem  doxygen 1.4.6