www.pudn.com > vc-ftp.rar > MultiFtpDownloadThread.cpp


//--------------------------------------------------------------------------- 
 
#include  
#pragma hdrstop 
 
#include "MultiFtpDownloadThread.h" 
#pragma package(smart_init) 
#include "MultiFtp.h" 
//--------------------------------------------------------------------------- 
 
//   Important: Methods and properties of objects in VCL can only be 
//   used in a method called using Synchronize, for example: 
// 
//      Synchronize(UpdateCaption); 
// 
//   where UpdateCaption could look like: 
// 
//      void __fastcall MultiFtpDownloadThread::UpdateCaption() 
//      { 
//        Form1->Caption = "Updated in a thread"; 
//      } 
//--------------------------------------------------------------------------- 
 
__fastcall MultiFtpDownloadThread::MultiFtpDownloadThread(bool CreateSuspended) 
        : TThread(CreateSuspended) 
{ 
} 
__fastcall MultiFtpDownloadThread::~MultiFtpDownloadThread() 
{ 
        closesocket(this->dataClient); 
        closesocket(this->commandClient); 
} 
//--------------------------------------------------------------------------- 
void __fastcall MultiFtpDownloadThread::Execute() 
{ 
        //---- Place thread code here ---- 
       TMultiFtp  * multiFtp = (TMultiFtp *)parent; 
       SetFilePos(multiFtp->inforImpl.fromToImpl[this->ID].from); 
       if(!CreateDataCon()) 
       { 
          multiFtp->runningThreadCnt --; 
          return; 
       } 
       String str = "RETR "+this->FileName+" \r\n"; 
       char *buffer = new char[100]; 
       int recLen ; 
       send(commandClient,str.c_str(),str.Length(),0); 
       this->DoOnTextOut(str.SubString(1,str.Length()-3)); 
       recLen = recv(commandClient,buffer,100,0); 
       this->DoOnTextOut(buffer); 
        buffer[recLen]=0; 
       if(multiFtp->GetCode(buffer) != "150") 
       { 
          Sleep(1000); 
          send(commandClient,str.c_str(),str.Length(),0); 
          this->DoOnTextOut("尝试第2次!"); 
          recv(commandClient,buffer,100,0); 
          this->DoOnTextOut(buffer); 
          if(multiFtp->GetCode(buffer) != "150") 
          { 
            Sleep(1000); 
            send(commandClient,str.c_str(),str.Length(),0); 
             this->DoOnTextOut("尝试第3次!"); 
            recv(commandClient,buffer,100,0); 
            this->DoOnTextOut(buffer); 
            if(multiFtp->GetCode(buffer) != "150") 
            { 
                this->DoOnException(buffer); 
                delete[] buffer; 
                multiFtp->runningThreadCnt --; 
                return; 
            } 
          } 
       } 
          this->DoOnTextOut("开始接受数据!"); 
        while(!multiFtp->stop && multiFtp->inforImpl.fromToImpl[this->ID].from < multiFtp->inforImpl.fromToImpl[this->ID].to) 
        { 
             if(multiFtp->inforImpl.fromToImpl[this->ID].to - multiFtp->inforImpl.fromToImpl[this->ID].from > (DWORD)multiFtp->PerGetLen) 
               { 
                 if(!DownLoad(multiFtp->inforImpl.fromToImpl[this->ID].from,multiFtp->PerGetLen)) 
                   break; 
               } 
             else 
                { 
                if(!DownLoad(multiFtp->inforImpl.fromToImpl[this->ID].from,multiFtp->inforImpl.fromToImpl[this->ID].to - multiFtp->inforImpl.fromToImpl[this->ID].from)) 
                    break; 
                } 
        } 
        delete[] buffer; 
        closesocket(this->dataClient); 
        closesocket(this->commandClient); 
        multiFtp->runningThreadCnt --; 
} 
bool __fastcall MultiFtpDownloadThread::DownLoad(DWORD pos ,DWORD len) 
{ 
    TMultiFtp  * multiFtp = (TMultiFtp *)parent; 
     char *buffer  = new char[len]; 
     DWORD cnt =0 ; 
     while(!multiFtp->stop && cnt < len) 
     { 
       int recLen = recv(this->dataClient,buffer+cnt,len-cnt,0); 
       if(recLen > 0) 
        { 
           cnt += recLen; 
           multiFtp->FilePos += recLen; 
           multiFtp->inforImpl.fromToImpl[this->ID].from += recLen; 
           this->DoOnProgress(multiFtp->FilePos); 
        } 
        else if(recLen < 0) 
        { 
            this->DoOnException("下载有误"); 
            break; 
        } 
        else 
        { 
          continue; 
        } 
     } 
    if(cnt < len || cnt == 0) 
       { 
        this->DoOnException("下载文件失败!"); 
        delete[] buffer; 
        return false; 
       } 
     else 
     { 
      //  this->DoOnTextOut("下载了一部分数据"); 
        multiFtp->WriteToFile(this->localFileLoad,pos,buffer,len); 
        multiFtp->WriteInforToFile(); 
       if(multiFtp->FilePos == multiFtp->fileSize) 
       { 
           this->DoOnComplete(); 
           multiFtp->WriteInforToFile(); 
           String profile = multiFtp->FileName+".san"; 
           fclose(multiFtp->globalFile); 
           String oldName = multiFtp->LocalLoad + ".nam"; 
           rename(oldName.c_str(),multiFtp->LocalLoad.c_str()); 
           DeleteFile(profile); 
        } 
     } 
     delete[] buffer; 
     return true; 
} 
bool __fastcall MultiFtpDownloadThread::SetFilePos(DWORD pos) 
{ 
   TMultiFtp  * multiFtp = (TMultiFtp *)parent; 
   int recLen ; 
   char * buffer = new char[100]; 
   String str = "REST "+IntToStr(pos)+" \r\n"; 
   this->DoOnTextOut(str); 
   send(this->commandClient,str.c_str(),str.Length(),0); 
   recLen = recv(commandClient,buffer,100,0); 
   buffer[recLen]=0; 
   if(multiFtp->GetCode(buffer) != "350") 
   { 
     this->DoOnException(buffer); 
     delete[] buffer; 
     return false; 
   } 
   this->DoOnTextOut(buffer); 
   delete[] buffer; 
   return true; 
} 
bool __fastcall MultiFtpDownloadThread::CreateDataCon() 
{ 
    char *port0= "PASV \r\n" ; 
    TMultiFtp  * multiFtp = (TMultiFtp *)parent; 
    this->DoOnTextOut(port0); 
    char *buffer = new char[100]; 
    int recLen ; 
    send(this->commandClient,port0,strlen(port0),0); 
    recLen = recv(commandClient,buffer,100,0); 
     buffer[recLen]=0; 
    if(multiFtp->GetCode(buffer) == "227") 
    { 
      this->DoOnTextOut(buffer); 
    } 
    else 
    { 
       this->DoOnException(buffer); 
       delete[] buffer; 
       return false; 
    } 
    MultiThreadDealSocket *dealSocket = new MultiThreadDealSocket(); 
    String host1 = dealSocket->GetHost(buffer); 
    int port1 = dealSocket->GetPort(buffer); 
    delete[] buffer; 
    this->dataClient = dealSocket->GetConnect(host1,port1); 
    if(this->dataClient != NULL) 
    { 
       this->DoOnTextOut("连接指定的断口成功!" ); 
      return true; 
    } 
    else 
    { 
       this->DoOnException("连接失败!!!"); 
       return false; 
    } 
} 
//--------------------------------------------------------------------------- 
void __fastcall MultiFtpDownloadThread::DoOnComplete() 
{ 
  if(this->FOnComplete) 
     this->FOnComplete(this->Owner); 
} 
void __fastcall MultiFtpDownloadThread::DoOnTextOut(String text) 
{ 
  if(this->FOnTextOut) 
  { 
     int index = text.Pos("\r\n"); 
     if(index > 0) 
       this->FOnTextOut(this->Owner,text.SubString(1,index-1)); 
     else 
       this->FOnTextOut(this->Owner,text); 
  } 
} 
void __fastcall MultiFtpDownloadThread::DoOnException(String error) 
{ 
   if(this->FOnException) 
   { 
      int index = error.Pos("\r\n"); 
      if(index > 0) 
      { 
        this->FOnException(this->Owner,error.SubString(1,index-1)); 
      } 
      else 
      { 
          this->FOnException(this->Owner,error); 
      } 
   } 
} 
void __fastcall MultiFtpDownloadThread::DoOnProgress(DWORD pos) 
{ 
  if(this->FOnProgress) 
    this->FOnProgress(this->Owner,pos); 
}