⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 multiftp.cpp

📁 使用vc++6.0开发的一个支持多线程ftp程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
     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;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -