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

📄 sendfile_cpp.cpp

📁 一个在delphi下用udp传输文件的实例
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    WriteFileSize=FileData.Position;    //取出并保存文件长度
    if (WriteListCount>0) delete [] WriteList;//删除文件块状态数据
    WriteListCount=0;                   //清文件块状态数
    div_t x;
    x=div(WriteFileSize,1000);          //计算文件块数量
    WriteListCount=x.quot;
    if (x.rem>0) WriteListCount++;
    WriteList=new bool [WriteListCount];//建立文件块状态数组
    for (int j=0;j<WriteListCount;j++) WriteList[j]=false;//置文件块状态
    try
    {
     WriteFile=new TFileStream(GetDir()+"\\"+FileName,fmCreate|fmShareDenyNone);//建立文件
     SendData_1("FRAll","",0);           //向发送方发出读文件指令
    }
    catch (...)
    {
     FRStatusBar->Panels->Items[1]->Text="建立"+FileName+"失败";
     SendData_1("FRErr","",0);              //向发送方发出写文件失败信息
    }
    TimerCount=0;                           //文件传送计时器
    Timer1->Enabled=true;
    FRBlocks=0;
    FRStatusBar->Panels->Items[2]->Text="00:00:00";
    FRError->Lines->Clear();
    FRError->Lines->Add("CRC错误的块");
    return;
   }
if (CMD=="FSFile")                        //发送方发来的是文件数据
   {
    if (WriteFile!=NULL)                  //有效的文件流
      {
       Cancel->Enabled=true;
       try
          {
           if (WriteFile->Size<=FileData.Position)      //当前块是文件尾(正常接收)
              FRStatusBar->Panels->Items[1]->Text=FormatFloat("###,###,###",FileData.Position+FileData.Size)+"/"+FormatFloat("###,###,###",WriteFileSize);
           else FRStatusBar->Panels->Items[1]->Text="纠错:"+IntToStr(FileData.Position);
           while (WriteFile!=NULL && WriteFile->Size<FileData.Position)    //如果当前块超过了文件尾
              {
               WriteFile->Seek(0,soFromEnd);            //写无用数据到文件
               WriteFile->WriteBuffer(FileData.Data,FileData.Size);
              }
           if (WriteFile==NULL) return ;
           WriteFile->Seek(FileData.Position,soFromBeginning);//写当前文件块
           WriteFile->WriteBuffer(FileData.Data,FileData.Size);
           FRBlocks++;
          }
       catch (...)
          {
           FRStatusBar->Panels->Items[1]->Text="写文件错误!";
           SendData_1("FRErr","",0);              //向发送方发出写文件错误信息
          }
      }
    return;
   }
if (CMD=="FSStop")                                //发送方发来的是文件发送结束指令
   {
    if (WriteFile!=NULL)                          //文件有效
      {
       int Poss[250];                             //需要重发的数据块
       int k=0;
       int j=0;
       FRError->Lines->Add("**需要重发的块**");
       while (j<WriteListCount-1)                 //搜索文件块数组
          {
           if (!WriteList[j])                     //错误的文件块
              {
              if (k<250)                          //一次最多发250个错误的文件块信息
                {
                 Poss[k]=j;                       //错误文件块编号数据
                 k++;                             //错误块计数器
                }
              FRError->Lines->Add(IntToStr(j*1000));
              }
           j++;
          }
       if (k>0)                                   //有错误的文件块
          {
           SendData_1("FRRead",(char *)Poss,k*sizeof(int));//向发送发错误块数据
          }
       else                                      //没有错误的数据块
          {
           delete WriteFile;                     //关闭文件
           WriteFile=NULL;
           FRBlocks=0;
           delete [] WriteList;                  //删除文件状态标志数组
           WriteListCount=0;                     //文件状态标志计数
           SendData_1("FREnd","",0);             //通知发送方文件传送完毕
           Timer1->Enabled=false;                //关闭文件传送计时器
           FRStatusBar->Panels->Items[1]->Text="接收完毕!";

          }
       }
    return;
   }
if (CMD=="FSCanc")                            //发送方发来的是中断命令
   {
    try
       {
        FileName=FileData.Data;               //取出文件文件名
        delete WriteFile;                     //关闭文件
        WriteFile=NULL;
        DeleteFile(GetDir()+"\\"+FileName);   //删除未接受完的文件
        SendData_1("FRCanc","",0);            //通知发送方已经中断
       }
    catch (...)
       {
       }
       FRStatusBar->Panels->Items[1]->Text="发送方中断传输";
    return;
   }

//************************执行重发命令*******************************

if (CMD=="FRRepa")                        //接收方发来的重发命令
   {
    SendData_1("FSLast","",0);            //执行发送方重发
    return;
   }
if (CMD=="FSRepa")                        //发送方发来的重发命令
   {
    SendData_1("FRLast","",0);            //执行接收方重发
    return;
   }

//************************以下是发送方命令处理程序********************
if (CMD=="FRRate")
   {
    memmove(&Rate,FileData.Data,sizeof(float));
    return;
   }
if (CMD=="FRCRC")                         //接收方发来的是CRC校验错信息
   {
    SendFile_1(FileData.Position);        //重发错误的文件块
    FSRepa->Lines->Add(IntToStr(FileData.Position));
    return;
   }
if (CMD=="FRCanc") return;              //接收方已经中断
if (CMD=="FRReje")                      //接收方发来拒绝接收指令
   {
    if (FSTimeOut>MaxTimeOut->Text.ToIntDef(60)) return;      //超时
    if (MessageDlg("对方拒绝接收,重试吗?",mtConfirmation,mbOKCancel,0)==mrOk)
       {
        SendData_1("FSLast","",0);        //重试
        return;
       }
    else CMD="FREnd";                   //结束发送
   }
if (CMD=="FRNot")                       //接收方发来文件无重名消息
   {
    if (FSTimeOut>MaxTimeOut->Text.ToIntDef(60)) return;      //超时
    StartSend();                        //开始发送文件
    return;
   }
if (CMD=="FRExis")                      //接收方发来文件重名消息
   {
    if (!Cancel->Enabled) return;       //已经Cancel
    if (FSTimeOut>MaxTimeOut->Text.ToIntDef(60)) return;      //超时
    FileName=FileData.Data;             //取出文件名,弹出对话框
    if (MessageDlg(FileName+"\r\n同名的文件已经存在,覆盖吗?",mtConfirmation,mbOKCancel,0)==mrOk)
      {
       StartSend();                     //开始发送文件
       return;
      }
    else CMD="FREnd";                   //用户选择"No",执行结束文件发送命令
   }
if (CMD=="FRAll")                       //接收方发来的是传送文件命令
   {
    if (ReadFile!=NULL)                 //文件有效
       {
        if (ReadFile->Position>0) return;//文件已经开始传送
        TimerCount=0;                   //文件传送计时器
        FSBlocks=0;
        Timer1->Enabled=true;
        FSStatusBar->Panels->Items[2]->Text="00:00:00";
        int Pos=0;
        while (Pos<ReadFileSize&&ReadFile!=NULL)//循环发送文件块
           {
            try
              {
               if (!Cancel->Enabled) return;//用户按下了"取消"健
               Pos+=SendFile_1(Pos);    //发送文件块
               if (Cancel->Enabled) FSStatusBar->Panels->Items[1]->Text=FormatFloat("###,###,###",Pos)+"/"+FormatFloat("###,###,###",ReadFileSize);
               else FSTimer->Enabled=false;
              }
            catch (...)
              {
              FSStatusBar->Panels->Items[1]->Text="读文件错误!";
              }
           }
        SendData_1("FSStop","",0);      //通知接收方传送完毕
       }
    else
       {
        FSStatusBar->Panels->Items[1]->Text="文件未打开!";
       }
    return;
   }
if (CMD=="FRRead")                      //发送方按接收方发来的块号传送文件块(用于纠错)
   {
    if (ReadFile!=NULL)
       {
        int Pos[250];                   //文件块号数组
        memmove(Pos,FileData.Data,FileData.Size);//取出接收方发来块号数据
        int n=FileData.Size/sizeof(int);//要发的块数量
        for (int j=0;j<n;j++)
           {
            try
              {
               if (!Cancel->Enabled) return;//用户按下了"取消"健
               SendFile_1(Pos[j]*1000); //发送所需要的文件块
               FSRepa->Lines->Add(IntToStr(Pos[j]*1000));
               if (Cancel->Enabled) FSStatusBar->Panels->Items[1]->Text="重发:"+FormatFloat("###,###,###",Pos[j]*1000);
               else FSTimer->Enabled=false;
              }
            catch (...)
              {
              FSStatusBar->Panels->Items[1]->Text="读文件错误!";
              }
           }
        SendData_1("FSStop","",0);      //通知接收方传输完毕
       }
    else
       {
        FSStatusBar->Panels->Items[1]->Text="文件未打开!";
       }
    return;
   }
if (CMD=="FRErr")                      //接收方发来写错误消息
   {
    if (MessageDlg("接收方写文件失败!重试吗?",mtConfirmation,mbOKCancel,0)==mrOk)
      {
       SendData_1("FSLast","",0);      //重发
       return;
      }
    else CMD="FREnd";                  //用户选择"No",执行结束文件发送命令
   }
if (CMD=="FREnd")                      //接收方发来文件传输结束信息
   {
   if (ReadFile==NULL)
      {
       FSStatusBar->Panels->Items[1]->Text="停止发送!";
       Sent->Enabled=false;                      //界面处理
       Cancel->Enabled=false;
       Add->Enabled=true;
       Clear->Enabled=true;
       SetUp->Enabled=true;
       return;
      }
   delete ReadFile;                    //关闭文件
   ReadFile=NULL;
   Timer1->Enabled=false;              //关闭文件传输计时器
   ListView1->Items->Delete(0);        //删掉已经发送的文件信息
   FullFileName->Delete(0);
   if (ListView1->Items->Count>0)      //还有未发送的文件
      {
       FSRepa->Lines->Clear();
       FRCMDS->Lines->Clear();
       FileName=ExtractFileName(FullFileName->Strings[0]);      //取出文件名
       SendData_1("FSName",FileName.c_str(),FileName.Length());   //发送文件名信息
       ListView1->ItemIndex=0;
      }
   else                                          //文件已经全部发送完毕
      {
       Sent->Enabled=false;                      //界面处理
       Cancel->Enabled=false;
       Add->Enabled=true;
       Clear->Enabled=true;
       SetUp->Enabled=true;
      }
    FSStatusBar->Panels->Items[1]->Text="发送完毕!";
    return;
   }
}
void __fastcall TSendFiles::FormCreate(TObject *Sender)
{
Dir->Text=GetCurrentDir();                       //初始路径(移植时要增加保存上次值的功能)
}
//---------------------------------------------------------------------------

void __fastcall TSendFiles::SentClick(TObject *Sender)  //发送按钮
{
AnsiString FileName;
FileName=ExtractFileName(FullFileName->Strings[0]);     //文件名
SendData_1("FSName",FileName.c_str(),FileName.Length());  //发送文件名信息
FSStatusBar->Panels->Items[1]->Text="";
FSStatusBar->Panels->Items[2]->Text="";
FSStatusBar->Panels->Items[3]->Text="";
ListView1->ItemIndex=0;

⌨️ 快捷键说明

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