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


//--------------------------------------------------------------------------- 
 
#include  
 
#pragma hdrstop 
 
#include "MultiFtp.h" 
#pragma package(smart_init) 
//--------------------------------------------------------------------------- 
// ValidCtrCheck is used to assure that the components created do not have 
// any pure virtual functions. 
// 
 
static inline void ValidCtrCheck(TMultiFtp *) 
{ 
        new TMultiFtp(NULL); 
} 
//--------------------------------------------------------------------------- 
__fastcall TMultiFtp::TMultiFtp(TComponent* Owner) 
        : TComponent(Owner) 
{ 
   lock = false; 
   isUseFile = false; 
   runningThreadCnt = 0; 
   stop = false; 
   this->Owner  = Owner; 
} 
__fastcall TMultiFtp::~TMultiFtp() 
{ 
    fclose(this->globalFile); 
    if(this->inforImpl.fromToImpl) 
      delete[] this->inforImpl.fromToImpl; 
} 
//--------------------------------------------------------------------------- 
namespace Multiftp 
{ 
        void __fastcall PACKAGE Register() 
        { 
                 TComponentClass classes[1] = {__classid(TMultiFtp)}; 
                 RegisterComponents("System", classes, 0); 
        } 
} 
//--------------------------------------------------------------------------- 
void __fastcall TMultiFtp::FreeMemory() 
{ 
    if(this->globalFile) 
       fclose(this->globalFile); 
    if(this->inforImpl.fromToImpl) 
      delete[] this->inforImpl.fromToImpl; 
} 
SOCKET __fastcall TMultiFtp::ConnectFtp(String host ,int port ,String userName ,String  pass) 
{ 
    this->DoOnTextOut("欢迎使用funinhand多线程,断点续传软件!!"); 
    MultiThreadDealSocket *dealSocket = new MultiThreadDealSocket(); 
    SOCKET client = dealSocket->GetConnect(host,port); 
    char * buffer = new char[100]; 
    int recLen ; 
    recLen = recv(client,buffer,100,0); 
    buffer[recLen]=0; 
    if(client == NULL) 
    { 
      this->DoOnException("连接ftp服务器失败!"); 
      delete[] buffer; 
      return NULL; 
    } 
    this->DoOnTextOut("连接ftp服务器成功!"); 
    String user = "USER  "+userName+" \r\n"; 
    this->DoOnTextOut(user); 
    send(client,user.c_str(),user.Length(),0); 
    recLen = recv(client,buffer,100,0); 
    buffer[recLen]=0; 
    if(GetCode(buffer) == "331") 
    { 
       this->DoOnTextOut("服务器要求验证密码。"); 
       String password = "PASS "+pass+" \r\n"; 
       this->DoOnTextOut(password); 
       send(client,password.c_str(),password.Length(),0); 
       recLen = recv(client,buffer,100,0); 
        buffer[recLen]=0; 
       int tryTimes = 3; 
       while(GetCode(buffer) != "230" && tryTimes > 0) 
       { 
          send(client,password.c_str(),password.Length(),0); 
          recLen = recv(client,buffer,100,0); 
           buffer[recLen]=0; 
          tryTimes --; 
          this->DoOnTextOut("第"+IntToStr(3-tryTimes)+"尝试"); 
       } 
       if(tryTimes < 0) 
       { 
           this->DoOnException(userName +"登录失败!"); 
           delete[] buffer; 
           return NULL; 
       } 
       else 
          this->DoOnTextOut("登录成功!"); 
    } 
    char *type = "TYPE I \r\n"; 
    this->DoOnTextOut(type); 
    send(client,type,strlen(type),0); 
    recLen = recv(client,buffer,100,0); 
     buffer[recLen]=0; 
    this->DoOnTextOut(buffer); 
    delete[] buffer; 
    return client; 
} 
void __fastcall TMultiFtp::SetStop(bool stop) 
{ 
  this->stop  = stop; 
} 
void __fastcall TMultiFtp::DoOnComplete() 
{ 
  if(this->FOnComplete) 
     this->FOnComplete(this->Owner); 
} 
void __fastcall TMultiFtp::DoOnGetFileSize(DWORD fileSize) 
{ 
   if(this->FOnGetFileSize) 
      this->FOnGetFileSize(this->Owner,fileSize); 
} 
void __fastcall TMultiFtp::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 TMultiFtp::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 TMultiFtp::DoOnProgress(DWORD pos) 
{ 
  if(this->FOnProgress) 
    this->FOnProgress(this->Owner,pos); 
} 
void  __fastcall TMultiFtp::DoOnGetRate(DWORD cnt) 
{ 
   if(this->FOnGetRate) 
      this->FOnGetRate(this->Owner,cnt); 
} 
String __fastcall TMultiFtp::GetCode(String revStr) 
{ 
  String str; 
  int index ; 
  index = revStr.Pos(" "); 
  str = revStr.SubString(1,index-1); 
  return str; 
} 
DWORD __fastcall TMultiFtp::GetFileSize() 
{ 
   return this->fileSize; 
} 
DWORD __fastcall TMultiFtp::GetFtpFileSize(SOCKET client ,String fileName) 
{ 
   String  size = "SIZE "+this->FFileName+" \r\n"; 
   this->DoOnTextOut(size); 
   send(client,size.c_str(),size.Length(),0); 
   char *buffer= new char[100]; 
   int recLen ; 
   recLen = recv(client,buffer,100,0); 
   buffer[recLen]=0; 
   this->DoOnTextOut(buffer); 
   if(GetCode(buffer) != "213") 
   { 
     this->DoOnTextOut("尝试第二次获取"); 
     send(client,size.c_str(),size.Length(),0); 
     recLen = recv(client,buffer,100,0); 
      buffer[recLen]=0; 
      this->DoOnTextOut(buffer); 
     if(GetCode(buffer) != "213") 
     { 
        this->DoOnTextOut("尝试第三次获取"); 
        send(client,size.c_str(),size.Length(),0); 
        recLen = recv(client,buffer,100,0); 
         buffer[recLen]=0; 
         this->DoOnTextOut(buffer); 
        if(GetCode(buffer) != "213") 
        { 
            this->DoOnException("获取文件大小失败!"); 
            delete[] buffer; 
             return 0; 
        } 
        else 
        { 
            this->DoOnTextOut(buffer); 
        } 
     } 
     else 
     { 
         this->DoOnTextOut(buffer); 
     } 
   } 
   else 
   { 
       this->DoOnTextOut(buffer); 
   } 
   String recvStr(buffer); 
   delete[] buffer; 
   int index =  recvStr.Pos("\r\n"); 
   recvStr = recvStr.SubString(1,index-1); 
   index = recvStr.Pos(" "); 
   recvStr = recvStr.SubString(index+1,recvStr.Length()- index); 
   this->fileSize  =StrToInt(recvStr); 
   return this->fileSize; 
} 
bool __fastcall  TMultiFtp::CheckIsSupportMulti(SOCKET client) 
{ 
   String rest = "REST 100 \r\n"; 
   char *buffer = new char[100]; 
   this->DoOnTextOut(rest); 
   int recLen ; 
   send(client,rest.c_str(),rest.Length(),0); 
   recLen = recv(client,buffer,100,0); 
   buffer[recLen]=0; 
   this->DoOnTextOut(buffer); 
   if(GetCode(buffer) != "350") 
   { 
       delete[] buffer; 
       return false; 
   } 
   delete[] buffer; 
   return true; 
} 
FileTail * __fastcall TMultiFtp::GetFilePosLen() 
{ 
   while(lock) 
   { 
     Sleep(50); 
   } 
   lock = true; 
   FileTail * temp  = new FileTail[1]; 
   if(this->currentFilePos >= fileSize) 
   { 
       lock = false; 
       temp->isOk = true; 
       return temp; 
   } 
   if(this->FPerGetLen + this->currentFilePos > fileSize) 
   { 
       temp->pos = ConvertIntToStr(this->currentFilePos); 
       temp->len = ConvertIntToStr(this->fileSize - this->currentFilePos); 
       temp->isOk = false; 
       this->currentFilePos = fileSize; 
       lock = false; 
       return temp; 
   } 
   temp->pos = ConvertIntToStr(this->currentFilePos); 
   temp->len = ConvertIntToStr(this->FPerGetLen); 
   temp->isOk = false; 
   this->currentFilePos = this->currentFilePos + this->FPerGetLen; 
   lock = false; 
   return  temp; 
} 
String __fastcall TMultiFtp::ConvertIntToStr(DWORD len) 
{ 
     String str; 
     str = IntToStr(len); 
     int strLen; 
     strLen = str.Length(); 
     for(int i =0 ; i < 10 -strLen ; i++) 
     { 
        str = "0"+str; 
     } 
     return str; 
} 
bool __fastcall TMultiFtp::ChangeDirectory(SOCKET client ,String dirName) 
{ 
    String dir =  "CWD "+dirName+" \r\n"; 
    this->DoOnTextOut(dir); 
    char *buffer = new char[100]; 
    int recLen ; 
    send(client,dir.c_str(),dir.Length(),0); 
    recLen = recv(client,buffer,100,0); 
    buffer[recLen]=0; 
    if(GetCode(buffer) != "250") 
    { 
        delete[] buffer; 
        this->DoOnException(buffer); 
        return false; 
    } 
    this->DoOnTextOut(buffer); 
    delete[] buffer; 
    return true; 
} 
void __fastcall TMultiFtp::StartDownloadFile() 
{ 
   SOCKET client = this->ConnectFtp(this->FHost,this->FPort,this->FUserName,this->FPass); 
   this->DoOnTextOut("下载的线程模块数为:"+IntToStr(this->FThreadCnt)); 
   if(!client) 
   { 
       return; 
   }  //连接ftp成功 
   if(!this->CheckIsSupportMulti(client)) 
   { 
      this->DoOnTextOut("该站点不支持断点续传。"); 
      this->FThreadCnt =  1;     //如果ftp服务器不支持多线程下载 
   } 
   this->DoOnTextOut("该站点支持断点续传。"); 
   ////////////将当前的工作目录设置成 
   this->FileName = this->SetCurrentDir(client,this->FilePath); 
   this->GetFtpFileSize(client,this->FileName); 
   this->DoOnGetFileSize(this->fileSize);  //输出文件大小 
   if(this->fileSize == 0) 
   { 
      closesocket(client); 
      return; 
   } 
   if(this->fileSize <= (DWORD)this->PerGetLen) 
   { 
      this->FThreadCnt = 1; 
   } 
   if(this->FileName == "") 
   { 
      closesocket(client); 
      return; 
   } 
   String hisFileName = this->FileName + ".san"; 
   ///////////////////检测是否断点续传///////////////////////// 
   if(FileExists(hisFileName)&& (GetFileSizeByName(hisFileName) > 0)) //如果文件存在 
   { 
      this->GetInfor(hisFileName); 
   } 
   else 
   { 
     globalFile = fopen(hisFileName.c_str(),"w+b"); 
     if(globalFile == NULL) 
     { 
      this->DoOnException("创建文件"+hisFileName+"失败"); 
      closesocket(client); 
          return ; 
     } 
     this->FilePos = this->perFilePos =  0; 
     this->CreateNewFile(this->LocalLoad,this->fileSize); 
     DivisionFile();  //// 
   } 
/////////////////////////////////////////////////////////// 
   if(this->inforImpl.alreadyDownloadCnt >= this->fileSize) 
   { 
       fclose(globalFile); 
       DeleteFile(hisFileName); 
       closesocket(client); 
       return; 
   } 
   //////////////把文件分割成几块进行下载 /////////// 
    this->DoOnTextOut("下载的线程模块数为:"+IntToStr(this->FThreadCnt)); 
   ////////////////////////////启动线程0////////////// 
     MultiFtpDownloadThread *thread = new MultiFtpDownloadThread(true); 
     this->runningThreadCnt ++; 
     if(this->stop) 
     { 
        closesocket(client); 
        return; 
     } 
     thread->parent = this; 
     thread->commandClient = client; 
     thread->localFileLoad = this->FLocalLoad; 
     thread->FOnComplete = this->FOnComplete; 
     thread->FOnException  = this->FOnException; 
     thread->FOnProgress = this->FOnProgress; 
     thread->FOnTextOut = this->FOnTextOut; 
     thread->FileName = this->FileName; 
     thread->Owner = this->Owner; 
     thread->perFileLen = this->PerGetLen; 
     thread->ID =  0; 
     thread->Resume(); 
   ////////////////////////////////////////////////////// 
   for(int i = 1; i < FThreadCnt ; i++) 
   { 
       SOCKET temp = this->ConnectFtp(this->FHost,this->FPort,this->FUserName,this->FPass); 
       this->CreateThread(i,temp); 
   } 
   ////////////保证有多个线程同步下载///////////// 
   while(true && !this->stop) 
   { 
        if(this->runningThreadCnt < this->FThreadCnt) 
        { 
            if(this->FilePos >= this->fileSize) 
              return; 
            int successCode = this->GetSuccessCode();  //取得已经完成的线程id 
            int busyCode = this->GetBusyCode();  //取得任务最重的线程id 
            if((this->inforImpl.fromToImpl[busyCode].to - this->inforImpl.fromToImpl[busyCode].from)< (DWORD)this->PerGetLen ) 
            { //如果当前的文件下载字节比一次最小要取得的字节数还小,就退出 
                return; 
            } 
            AverageDownload(successCode,busyCode); 
            Sleep(1000); 
        } 
        else 
        { 
           Sleep(1000); 
        } 
   } 
 
} 
DWORD __fastcall TMultiFtp::GetFileSizeByName(String fileName) 
{ 
    FILE *file ; 
    DWORD  dataLen; 
    file = fopen(fileName.c_str(),"r+b"); 
    if(file ==  NULL) return 0; 
    fseek(file,0,2); 
    dataLen = ftell(file); 
    fclose(file); 
    return dataLen; 
} 
void __fastcall TMultiFtp::AverageDownload(int successCode , int busyCode) 
{ 
   DWORD per  = (this->inforImpl.fromToImpl[busyCode].to - this->inforImpl.fromToImpl[busyCode].from - this->FPerGetLen) /2; 
   DWORD successFrom = this->inforImpl.fromToImpl[busyCode].to - per; 
   this->inforImpl.fromToImpl[successCode].from = successFrom; 
   this->inforImpl.fromToImpl[successCode].to = this->inforImpl.fromToImpl[busyCode].to; 
   this->inforImpl.fromToImpl[busyCode].to = successFrom; 
   SOCKET temp = this->ConnectFtp(this->FHost,this->FPort,this->FUserName,this->FPass);   //开始下载 
   this->CreateThread(successCode,temp); 
} 
void  __fastcall   TMultiFtp::CreateThread(int code ,SOCKET client) 
{ 
       MultiFtpDownloadThread *thread = new MultiFtpDownloadThread(true); 
       this->runningThreadCnt ++; 
       this->SetCurrentDir(client,this->FilePath); 
       if(this->stop) 
       { 
         closesocket(client); 
          return; 
       } 
       thread->parent = this; 
       thread->commandClient = client; 
       thread->localFileLoad = this->FLocalLoad; 
       thread->FOnComplete = this->FOnComplete; 
       thread->FOnException  = this->FOnException; 
       thread->FOnProgress = this->FOnProgress; 
       thread->FOnTextOut = this->FOnTextOut; 
       thread->FileName = this->FileName; 
       thread->Owner = this->Owner; 
       thread->perFileLen = this->PerGetLen; 
       thread->ID =  code; 
       thread->Resume(); 
} 
String __fastcall  TMultiFtp::SetCurrentDir(SOCKET client ,String fileName) 
{ 
    int index; 
    index = fileName.Pos("/"); 
    String temp; 
    char *buffer = new char[100]; 
    while(index > 0) 
    { 
      temp = fileName.SubString(1,index-1); 
      String curDir = "PWD \r\n"; 
      send(client,curDir.c_str(),curDir.Length(),0); 
      int recLen = recv(client,buffer,100,0); 
      buffer[recLen] = 0; 
      if(!this->ChangeDirectory(client,temp)) 
      { 
          delete[] buffer; 
          return ""; 
      } 
      fileName = fileName.SubString(index+1,fileName.Length()- index); 
      index = fileName.Pos("/"); 
    } 
    delete[] buffer; 
    return fileName; 
} 
void __fastcall TMultiFtp::WriteToFile(String filePath,DWORD pos ,char *buffer , int len) 
{ 
   String tempFileName = filePath + ".nam"; 
    while(isUseFile) 
       Sleep(50); 
    isUseFile = true; 
    FILE *file ; 
    file = fopen(tempFileName.c_str(),"r+b"); 
    if(file == NULL) { 
    String str  = this->FileName + ".san"; 
    fclose(this->globalFile); 
    DeleteFile(str); 
    this->DoOnException("写入文件失败!"); 
    isUseFile = false; 
    return; 
    } ; 
    fseek(file,pos,0); 
    fwrite(buffer,sizeof(char),len,file); 
    fclose(file); 
    isUseFile = false; 
} 
bool __fastcall TMultiFtp::CreateNewFile(String fileName, DWORD size) 
{ 
   String tempFileName = fileName + ".nam"; 
   FILE  *file; 
   file = fopen(tempFileName.c_str(),"w+b"); 
   if(file == NULL) return false; 
   this->DoOnTextOut("正在创建文件,请稍候..."); 
   char * buffer  = new char[60000]; 
   memset(buffer,'0',60000); 
   DWORD writeLen = 0; 
   int needLen = 60000; 
   while(writeLen < size) 
   { 
     if(writeLen + 60000 > size) 
     { 
        needLen = size -writeLen; 
     } 
     else 
        needLen = 60000; 
     int len =  fwrite(buffer,sizeof(char),needLen,file); 
     if(len > 0)  writeLen += len; 
  } 
  delete[]  buffer; 
    fclose(file); 
    return true; 
} 
bool __fastcall TMultiFtp::WriteInforToFile() 
{ 
   String writeStr ; 
   String fileSizeStr = IntToStr(this->fileSize); 
   String threadCntStr = IntToStr(this->inforImpl.threadCnt); 
   String downloadCntStr = IntToStr(this->FilePos); 
   writeStr = this->LocalLoad+"\r\n"+fileSizeStr+"\r\n"+threadCntStr+"\r\n"+downloadCntStr+"\r\n"; 
   for(int i = 0; i< this->inforImpl.threadCnt ; i++) 
   { 
     writeStr += IntToStr(this->inforImpl.fromToImpl[i].from) +"-"+IntToStr(this->inforImpl.fromToImpl[i].to)+"\r\n"; 
   } 
   while(this->FileLocked) Sleep(10); 
   FileLocked = true; 
   if(this->globalFile == NULL) 
   { 
     FileLocked = false; 
     return false; 
   } 
   try 
   { 
     fseek(this->globalFile,0,0); 
     fwrite(writeStr.c_str(),sizeof(char),writeStr.Length(),this->globalFile); 
     FileLocked = false; 
     return true; 
   } 
   catch(...) 
   { 
       FileLocked = false; 
     return false; 
   } 
 
} 
void __fastcall  TMultiFtp::DivisionFile() 
{ 
  this->fromToImpl = new FromToImpl[this->FThreadCnt]; 
  this->inforImpl.fileLoad = this->FLocalLoad; 
  this->inforImpl.fileSize = this->fileSize; 
  this->inforImpl.threadCnt = this->FThreadCnt; 
  this->inforImpl.alreadyDownloadCnt = this->FilePos; 
   this->inforImpl.fromToImpl = new FromToImpl[this->FThreadCnt]; 
  DWORD perCnt = this->fileSize / this->FThreadCnt; 
  int i; 
  for(i = 0 ;i < this->FThreadCnt-1 ; i++) 
  { 
     this->inforImpl.fromToImpl[i].from =  perCnt * i; 
     this->inforImpl.fromToImpl[i].to = perCnt*(i+1); 
  } 
     this->inforImpl.fromToImpl[i].from =  perCnt*(i); 
     this->inforImpl.fromToImpl[i].to = this->fileSize; 
    this->WriteInforToFile(); 
} 
void __fastcall TMultiFtp::DealTimer(MSG msg) 
{ 
   DWORD desLen = this->FilePos  - this->perFilePos; 
   this->DoOnGetRate(desLen);  
} 
void __fastcall  TMultiFtp::GetInfor(String fileName) 
{ 
   char *buffer = new char[5000]; 
   while(this->FileLocked) Sleep(50); 
   this->FileLocked = true; 
   globalFile = fopen(fileName.c_str(),"r+b"); 
   fseek(this->globalFile,0,2); 
   int fileLen = ftell(this->globalFile); 
   fseek(this->globalFile,0,0); 
   int readLen = fread(buffer,sizeof(char),fileLen,this->globalFile); 
   buffer[readLen] = 0; 
   String str(buffer); 
   this->hisFileStr = str; 
   delete[] buffer; 
  this->FileLocked = false; 
  CreateInforImpl(str); 
} 
void __fastcall TMultiFtp::CreateInforImplFromString(String inforStr) 
{ 
   int index; 
   String temp; 
   index = hisFileStr.Pos("\r\n"); 
   this->FLocalLoad =  hisFileStr.SubString(1,index-1);             //获取了文件的保存地址 
   hisFileStr = hisFileStr.SubString(index+2,hisFileStr.Length()-index); 
   index = hisFileStr.Pos("\r\n"); 
   this->fileSize = StrToInt(hisFileStr.SubString(1,index-1)); //获取了文件大小 
   hisFileStr = hisFileStr.SubString(index+2,hisFileStr.Length() -index); 
   index = hisFileStr.Pos("\r\n"); 
   this->ThreadCnt = StrToInt(hisFileStr.SubString(1,index-1)); //获取了线程数目 
   hisFileStr = hisFileStr.SubString(index+2,hisFileStr.Length() - index); 
   index = hisFileStr.Pos("\r\n"); 
   this->FilePos  = StrToInt(hisFileStr.SubString(1,index-1));             //获取了已经下载文件的大小 
   hisFileStr = hisFileStr.SubString(index+2,hisFileStr.Length() - index); 
   ////付值给全局变量 
   this->inforImpl.fromToImpl = new FromToImpl[ThreadCnt]; 
   this->inforImpl.fileLoad = this->FLocalLoad; 
   this->inforImpl.fileSize = this->fileSize; 
   this->inforImpl.threadCnt = this->ThreadCnt; 
   this->inforImpl.alreadyDownloadCnt = this->FilePos; 
   String from ,to; 
   for(int i =0 ;i < this->ThreadCnt ; i++) 
   { 
      index = hisFileStr.Pos("\r\n"); 
      temp = hisFileStr.SubString(1,index-1); // 获取from  - to 值 
      hisFileStr = hisFileStr.SubString(index +2 ,hisFileStr.Length() - index); 
      index = temp.Pos("-"); 
      from  = temp.SubString(1,index-1); 
      to = temp.SubString(index+1,temp.Length() - index); 
      this->inforImpl.fromToImpl[i].from = StrToInt(from); 
      this->inforImpl.fromToImpl[i].to = StrToInt(to); 
   } 
} 
void __fastcall TMultiFtp::CreateInforImpl(String str) 
{     //一些断点续传的参数 
   int index; 
   String temp; 
   index = hisFileStr.Pos("\r\n"); 
   this->FLocalLoad =  hisFileStr.SubString(1,index-1);             //获取了文件的保存地址 
   hisFileStr = hisFileStr.SubString(index+2,hisFileStr.Length()-index); 
   index = hisFileStr.Pos("\r\n"); 
   this->fileSize = StrToInt(hisFileStr.SubString(1,index-1)); //获取了文件大小 
   hisFileStr = hisFileStr.SubString(index+2,hisFileStr.Length() -index); 
   index = hisFileStr.Pos("\r\n"); 
   this->ThreadCnt = StrToInt(hisFileStr.SubString(1,index-1)); //获取了线程数目 
   hisFileStr = hisFileStr.SubString(index+2,hisFileStr.Length() - index); 
   index = hisFileStr.Pos("\r\n"); 
   this->FilePos  = StrToInt(hisFileStr.SubString(1,index-1));             //获取了已经下载文件的大小 
   hisFileStr = hisFileStr.SubString(index+2,hisFileStr.Length() - index); 
   ////付值给全局变量 
   this->inforImpl.fromToImpl = new FromToImpl[ThreadCnt]; 
   this->inforImpl.fileLoad = this->FLocalLoad; 
   this->inforImpl.fileSize = this->fileSize; 
   this->inforImpl.threadCnt = this->ThreadCnt; 
   this->inforImpl.alreadyDownloadCnt = this->FilePos; 
   String from ,to; 
   for(int i =0 ;i < this->ThreadCnt ; i++) 
   { 
      index = hisFileStr.Pos("\r\n"); 
      temp = hisFileStr.SubString(1,index-1); // 获取from  - to 值 
      hisFileStr = hisFileStr.SubString(index +2 ,hisFileStr.Length() - index); 
      index = temp.Pos("-"); 
      from  = temp.SubString(1,index-1); 
      to = temp.SubString(index+1,temp.Length() - index); 
      this->inforImpl.fromToImpl[i].from = StrToInt(from); 
      this->inforImpl.fromToImpl[i].to = StrToInt(to); 
   } 
} 
int __fastcall TMultiFtp::GetSuccessCode()   //返回已经完成的线程id 
{ 
    for(int i = 0 ;i < this->FThreadCnt; i ++) 
    { 
       if(this->inforImpl.fromToImpl[i].from == this->inforImpl.fromToImpl[i].to) 
       { 
         return i; 
       } 
    } 
    return -1; 
} 
int __fastcall TMultiFtp::GetBusyCode() //返回任务最多的线程id 
{ 
   int code = -1 ; 
   DWORD descLen =0 ; 
    for(int i = 0; i < this->FThreadCnt; i++) 
    { 
         if( (this->inforImpl.fromToImpl[i].to - this->inforImpl.fromToImpl[i].from ) > descLen) 
           { 
              descLen =  this->inforImpl.fromToImpl[i].to - this->inforImpl.fromToImpl[i].from ; 
              code= i; 
           } 
    } 
    return code; 
}