📄 evafiledownloader.cpp
字号:
/*************************************************************************** * Copyright (C) 2005 by yunfan * * yunfan_zg@163.com * * * * 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 "evafiledownloader.h"#include "evacachedfile.h"#include "evaftprotocols.h"#include "../../libeva/evautil.h"#include "../../libeva/evadefines.h"#include <qdns.h>#include <qtextcodec.h>#include <qapplication.h>#define RELAY_SERVER_URL "RelayServer2.tencent.com"#define RELAY_SERVER_DEFAULT_IP "219.133.40.38"#define RELAY_SERVER_PORT 443#define SYN_SERVER_URL "synserver.tencent.com"#define SYN_SERVER_DEFAULT_IP "219.133.49.80"#define SYN_SERVER_PORT 8000#define QQ_TRANSFER_FILE 0x65#define QQ_TRANSFER_IMAGE 0x66EvaFileThread::EvaFileThread(QObject *receiver, const int id, const QValueList<QString> &dirList, const QValueList<QString> &filenameList, const QValueList<unsigned int> sizeList, const bool isSender) : QObject(), QThread(), m_IsSender(isSender), m_Receiver(receiver), m_Id(id), m_Session(0), m_StartOffset(0), m_ExitNow(false), m_BytesSent(0), m_File(NULL), m_Connecter(NULL){ if(dirList.size() != filenameList.size()) { m_ExitNow = true; return; } m_DirList = dirList; m_FileNameList = filenameList; m_SizeList = sizeList; EvaCachedFile *file; for(unsigned int i = 0; i < dirList.size(); ++i){ printf("EvaFileThread::EvaFileThread -- dir: %s\t filename:%s\n", dirList[i].ascii(), filenameList[i].ascii()); if(m_IsSender) file = new EvaCachedFile(dirList[i], filenameList[i]); else file = new EvaCachedFile(dirList[i], filenameList[i], sizeList[i]); m_FileList.append(file); } m_FileList.setAutoDelete(true); m_File = m_FileList.first(); m_Dir = dirList.first(); m_FileName = filenameList.first();}EvaFileThread::~EvaFileThread(){ cleanUp();}void EvaFileThread::setDir( const QString & dir ){ if(!m_DirList.count()) return; m_Dir = dir; if(!m_File) return; m_File->setDestFileDir(dir); m_DirList[0] = m_Dir; // for file transfer, one file each session, not like images}const QString EvaFileThread::getDir() const{ return m_Dir;}const unsigned int EvaFileThread::getFileSize(){ if(!m_File) return 0; return m_File->getFileSize();}void EvaFileThread::notifyTransferStatus(){ int timeElapsed = m_StartTime.secsTo(QDateTime::currentDateTime()); EvaFileNotifyStatusEvent *event = new EvaFileNotifyStatusEvent(); event->setFileSize(m_File->getFileSize()); event->setBytesSent(m_StartOffset + m_BytesSent); event->setTimeElapsed(timeElapsed); event->setSession(m_Session); event->setBuddyQQ(m_Id); QApplication::postEvent(m_Receiver, event);}void EvaFileThread::notifyNormalStatus(const EvaFileStatus status){ EvaFileNotifyNormalEvent *event = new EvaFileNotifyNormalEvent(); event->setSession(m_Session); event->setBuddyQQ(m_Id); event->setStatus(status); event->setFileName(m_FileName); event->setFileDir(m_Dir); event->setTransferType(m_TransferType); if(status == ESResume){ event->setFileSize(m_File->getNextOffset()); } else event->setFileSize(m_File->getFileSize()); QApplication::postEvent(m_Receiver, event);}void EvaFileThread::cleanUp(){ m_FileList.clear(); m_DirList.clear(); m_FileNameList.clear(); m_SizeList.clear();// if(m_File) delete m_File; if(m_Connecter) delete m_Connecter;}/** ================================================================== */EvaAgentThread::EvaAgentThread(QObject *receiver, const int id, const QValueList<QString> &dirList, const QValueList<QString> &filenameList, QValueList<unsigned int> sizeList, const bool isSender) : EvaFileThread(receiver, id, dirList, filenameList, sizeList, isSender), m_State(ENone), m_Token(NULL), m_TokenLength(0), m_ServerPort(RELAY_SERVER_PORT), m_BufferLength(0), m_PacketLength(0), m_UsingProxy(false){}EvaAgentThread::~ EvaAgentThread(){ if(m_Token) delete []m_Token;}void EvaAgentThread::setFileAgentToken(const unsigned char *token, const int len){ if(!token) return; if(m_Token) delete [] m_Token; m_Token = new unsigned char[len]; memcpy(m_Token, token, len); m_TokenLength = len;}void EvaAgentThread::setFileAgentKey(const unsigned char *key){ memcpy(m_FileAgentKey, key, 16);}void EvaAgentThread::setServerAddress(const unsigned int ip, const unsigned short port){ m_HostAddresses.clear(); m_HostAddresses.append(QHostAddress(ip)); m_ServerPort = port;}void EvaAgentThread::setProxySettings(const QHostAddress addr, const short port, const QCString ¶m){ m_ProxyServer = addr; m_ProxyPort = port; m_ProxyAuthParam = param; m_UsingProxy = true;}void EvaAgentThread::doCreateConnection(){ if(m_Connecter){ m_Connecter->close(); delete m_Connecter; } if(m_UsingProxy){ m_Connecter = new EvaNetwork(m_ProxyServer, m_ProxyPort, EvaNetwork::HTTP_Proxy); m_Connecter->setDestinationServer(m_HostAddresses.first().toString(), m_ServerPort); m_Connecter->setAuthParameter(m_ProxyAuthParam); }else m_Connecter = new EvaNetwork(m_HostAddresses.first(), m_ServerPort, EvaNetwork::TCP); QObject::connect(m_Connecter, SIGNAL(isReady()), SLOT(slotNetworkReady())); QObject::connect(m_Connecter, SIGNAL(dataComming(int)), SLOT(slotDataComming(int))); QObject::connect(m_Connecter, SIGNAL(exceptionEvent(int)), SLOT(slotNetworkException(int))); m_Connecter->connect(); m_State = ENone;}void EvaAgentThread::send(EvaFTAgentPacket *packet){ if(! m_Connecter ){ fprintf(stderr, "EvaAgentThread::send -- Network invalid!\n"); delete packet; m_State = EError; return; } // set the header information & key packet->setFileAgentKey(m_FileAgentKey); packet->setQQ(m_MyId); packet->setVersion(QQ_CLIENT_VERSION); packet->setSequence(m_Sequence); packet->setSessionId(m_Session); unsigned char *buffer = new unsigned char[4096]; int len = 0; packet->fill(buffer, &len); if(!m_Connecter->write((char *)buffer, len)){ delete []buffer; delete packet; m_State = EError; return; } delete []buffer; delete packet;}void EvaAgentThread::processAgentPacket( unsigned char * /*data*/, int /*len*/ ){ fprintf(stderr, "EvaAgentThread::processAgentPacket -- Not Implemented, Error!\n"); m_State = EError;}void EvaAgentThread::slotNetworkReady(){ printf("EvaAgentThread::slotNetworkReady\n"); m_State = ENetworkReady;}void EvaAgentThread::slotDataComming(int len){ if(m_Connecter->connectionType() != EvaNetwork::UDP){ char *rawData = new char[len+1]; if(!m_Connecter->read(rawData, len)){ fprintf(stderr, "EvaAgentThread::slotDataComming -- Bytes read wrong, ignore!\n"); delete []rawData; return; } memcpy(m_Buffer + m_BufferLength, rawData, len); m_BufferLength += len; delete []rawData; m_PacketLength = EvaUtil::read16(m_Buffer + 3); while(m_BufferLength >= m_PacketLength){ rawData = new char[m_PacketLength]; memcpy(rawData, m_Buffer, m_PacketLength); memcpy(m_Buffer, m_Buffer + m_PacketLength, m_BufferLength - m_PacketLength); len = m_PacketLength; m_BufferLength -= m_PacketLength; processAgentPacket((unsigned char *)rawData, len); delete []rawData; if(!m_BufferLength) break; m_PacketLength = EvaUtil::read16(m_Buffer + 3); } }}void EvaAgentThread::slotNetworkException(int no){ fprintf(stderr, "EvaAgentThread::slotNetworkException -- no: %d\n", no); if(m_State != EFinished) m_State = EError;}/** ================================================================== */EvaAgentUploader::EvaAgentUploader(QObject *receiver, const int id, const QValueList<QString> &dirList, const QValueList<QString> &filenameList) : EvaAgentThread(receiver, id, dirList, filenameList, QValueList<unsigned int>(), true), m_IsSendingStart(false), m_Dns(NULL){ m_Sequence = 0x0005;// give it a random number anyway m_OutBufferLength = 50 * EVA_FILE_BUFFER_UNIT; m_OutBuffer = new unsigned char[m_OutBufferLength]; m_NumPackets = 0; // send 50 packets every time if the left data is enough m_OutBytesSent = 0;}EvaAgentUploader::~EvaAgentUploader(){ if(m_Dns) delete m_Dns; if(m_OutBuffer) delete m_OutBuffer;}void EvaAgentUploader::run(){ printf("EvaAgentUploader::run \n"); m_State = EDnsQuery; while(!m_ExitNow){ switch(m_State){ case ENone: break; case EDnsQuery: doDnsRequest(); break; case EDnsReady: doCreateConnection(); break; case ENetworkReady: doCreateRequest(); break; case ECreatingReady: doNotifyBuddy(); break; case ENotifyReady: doReadyReply(); break; case EAskForStart: doStartRequest(); doSendInfo(); break; case ETransfer: doDataTransfering(); break; case EFinished: doFinishProcessing(); break; case EError: doErrorProcessing(); break; default: break; } msleep( 200 ); }}void EvaAgentUploader::doDnsRequest(){ printf("EvaAgentUploader::doDnsRequest\n"); m_HostAddresses.clear(); if(m_Dns) delete m_Dns; m_Dns = new QDns(RELAY_SERVER_URL); QObject::connect(m_Dns, SIGNAL(resultsReady()), SLOT(slotDnsReady())); // while(!m_HostAddresses.size()){// printf("EvaAgentUploader::doDnsRequest -- waiting for DNS results\n");// if(m_ExitNow) break;// msleep(200);// } m_State = ENone;}void EvaAgentUploader::slotDnsReady(){ m_HostAddresses = m_Dns->addresses(); if(!m_HostAddresses.size()){ QHostAddress host; host.setAddress(RELAY_SERVER_DEFAULT_IP); m_HostAddresses.append(host); } m_State = EDnsReady;}void EvaAgentUploader::doCreateRequest(){ if(!m_Token){ m_State = EError; return; } connect(m_Connecter, SIGNAL(writeReady()), SLOT(slotWriteReady())); m_Sequence++; EvaFTAgentCreate *packet = new EvaFTAgentCreate(); packet->setBuddyQQ(m_Id); packet->setIp(m_BuddyIp); packet->setFileAgentToken(m_Token, m_TokenLength); send(packet); m_State = ENone; // waiting the response from server printf("EvaAgentUploader::doCreateRequest\n");}void EvaAgentUploader::doNotifyBuddy(){ EvaFileNotifyAgentEvent *event = new EvaFileNotifyAgentEvent(); event->setOldSession(m_Session); event->setAgentSession(m_AgentSession); event->setAgentIp(m_HostAddresses.first().ip4Addr()); event->setAgentPort(m_ServerPort); event->setMyFileAgentKey(m_FileAgentKey); event->setBuddyQQ(m_Id); event->setTransferType(m_TransferType); QApplication::postEvent(m_Receiver, event); m_Session = m_AgentSession; // now we use agent session m_State = ENone;}void EvaAgentUploader::doReadyReply(){ EvaFTAgentAckReady *readyPacket = new EvaFTAgentAckReady(); send(readyPacket); m_State = EAskForStart;}void EvaAgentUploader::doStartRequest(){ EvaFTAgentStart *startPacket = new EvaFTAgentStart(); send(startPacket);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -