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

📄 unitsendfile.cpp

📁 BCB串口通讯控件
💻 CPP
字号:
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "UnitSendFile.h"
#include "yb_base.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "YbCommDevice"
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
  PkgID = 0;
  dlpath.Relative = "download";
  nBytesToReceive = 0;
  iReceiveFileTime = 0;
  bUploading = false;
  iReceivingCounter = 0;

  TBinFileFuncs::MkDir(AnsiString(dlpath).c_str());
  YbCommDevice1->PackageType = cptFrameHeadTail;
  YbCommDevice1->PackageSize = 9000; //最大允许发送9000字节的数据包
  YbCommDevice1->UsePackage  = true;

  YbCommDevice1->FrameSettings->FrameHead = 0xdb; //数据包头
  YbCommDevice1->FrameSettings->FrameTail = 0xde; //数据包尾
  YbCommDevice1->FrameSettings->FrameCtrl = 0xdc; //数据控制符

  try
   {
     YbCommDevice1->Active = true;
   }
  catch(Exception &e)
   {
     if(!YbCommDevice1->SettingsDialog(this,true))
       Application->Terminate();
   }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ShowInfo(AnsiString s)
{
  Memo1->Lines->Add(FormatDateTime("yyyy-mm-dd hh:nn:ss ",Now())+s);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FileOpen1Accept(TObject *Sender)
{
  try
   {
     bUploading = true;
     int nCode = UploadReq(FileOpen1->Dialog->FileName);
     if(nCode==0x88)nCode = UploadFileData();

     switch(nCode)
      {
        case 0x88: ShowInfo("发送成功!"); break;
        case 0xee: ShowInfo("发送文件错误!"); break;
        default  : ShowInfo("超时,对方电脑没有反应。");break;
      }
   }
  __finally
   {
     bUploading = false;
     sf.Active = false; //关闭文件
   }
}
//---------------------------------------------------------------------------
int __fastcall TForm1::UploadReq(AnsiString fname)
{
  sf.FileName = fname;
  sf.OpenMode = TBinFile::omRead;
  sf.Active = true;

  TMyFinfoPkg finf; //发送文件信息数据包
  finf.cmd  = mpcUpload;
  finf.id = PkgID++;
  TBinFileFuncs::GetFileName(finf.name, sf.FileName.c_str());
  finf.size = sf.Size;
  finf.time = sf.Time;
  finf.CRC = ~TCRC32().Check(&finf, sizeof(TMyFinfoPkg)-4);

  YbCommDevice1->WritePackage(&finf, sizeof(TMyFinfoPkg));
  ShowInfo("发送文件: "+sf.FileName);
  return WaitforAnswer(finf.cmd, finf.id);
}
//---------------------------------------------------------------------------
int __fastcall TForm1::UploadFileData(void)
{
  TMyFdataPkg fdata; //发送文件内容数据包
  long nFileSize = sf.Size, nTries;
  fdata.cmd = mpcFileData; //发送文件数据
  fdata.from = 0; //从文件第0个字节开始发送

  while((fdata.size=sf.Read(fdata.data,DataSize))>0)
   {
     fdata.id = PkgID++;
     fdata.CRC = ~TCRC32().Check(&fdata,sizeof(TMyFdataPkg)-4);

     for(nTries=2; nTries>0; nTries--)
      {
        YbCommDevice1->WritePackage(&fdata,sizeof(TMyFdataPkg));
        if(WaitforAnswer(fdata.cmd, fdata.id)==0x88)
          break;
      }
     if(!nTries)
      {
        return 0xee;
      }

     fdata.from += fdata.size;
     ProgressBar1->Position = TBinFileFuncs::MakePercent(fdata.from, nFileSize);
   }
  return 0x88;
}
//---------------------------------------------------------------------------
int __fastcall TForm1::WaitforAnswer(unsigned char Cmd, unsigned char id)
{
  TMyStatusPkg AnsPkg; //对方电脑回应的数据包
  int tm_start=timeGetTime(), tm_out=2000;
  while((int)(timeGetTime()-tm_start)<tm_out)
   {
     if(YbCommDevice1->ReadPackage(&AnsPkg,sizeof(TMyStatusPkg))==sizeof(TMyStatusPkg))
      if((AnsPkg.cmd==mpcStatus) && (AnsPkg.id==id) && (AnsPkg.anscmd==Cmd))
       {
         if(AnsPkg.status == 0x88)
           return 0x88; //ok
         return 0xee; //error
       }
     Application->ProcessMessages();
   }
  return 0; //timeout
}
//---------------------------------------------------------------------------
void __fastcall TForm1::YbCommDevice1Package(TObject *Sender, int NotifyType)
{
  if((NotifyType==EV_RXCHAR) && !bUploading)
   {
     typedef union
      {
        TMyFinfoPkg finfo; //文件信息数据包
        TMyFdataPkg fdata; //文件内容数据包
        unsigned char cmd;  //无论哪种数据包,第一个字节都是命令字节
      } TMyPackage;
     TMyPackage recv; //收到的数据包可能是文件信息或者文件内容
     TMyStatusPkg send; //发送回应状态数据包
     int nReceived; //收到的字节数

     while((nReceived=YbCommDevice1->ReadPackage(&recv,sizeof(TMyPackage)))>4) //数据包的长度都大于4
      {
        if(recv.cmd==mpcUpload)
         {
           send.cmd    = mpcStatus;
           send.id     = recv.finfo.id;
           send.anscmd = recv.finfo.cmd;
           send.status = (recv.finfo.CRC == ~TCRC32().Check(&recv,nReceived-4))?0x88:0xee;
           send.CRC = ~TCRC32().Check(&send,sizeof(TMyStatusPkg)-4);

           if(send.status==0x88) //数据 CRC 校验正确
            {
              iReceivingCounter = 5; //超过5秒没有数据,认为超时,中断接收
              nBytesToReceive = recv.finfo.size;
              iReceiveFileTime = recv.finfo.time;
              df.FileName = dlpath.FileName(recv.finfo.name);
              df.OpenMode = TBinFile::omCreateNew;
              df.Active = true;
              ShowInfo("接收文件: "+df.FileName);

              if(nBytesToReceive<=0)
               {
                 df.Time = iReceiveFileTime;
                 df.Active = false;
                 ShowInfo("接收完成!");
               }
            }
           YbCommDevice1->WritePackage(&send,sizeof(TMyStatusPkg));
         }
        else if(recv.cmd==mpcFileData)
         {
           send.cmd    = mpcStatus;
           send.id     = recv.fdata.id;
           send.anscmd = recv.fdata.cmd;
           send.status = recv.fdata.CRC == ~TCRC32().Check(&recv,nReceived-4)?0x88:0xee;
           send.CRC    = ~TCRC32().Check(&send,sizeof(TMyStatusPkg)-4);

           if((send.status==0x88) && (df.Active)) //数据 CRC 校验正确
            {
              iReceivingCounter = 5; //超过5秒没有数据,认为超时,中断接收
              df.Pos = recv.fdata.from;
              df.Write(recv.fdata.data,recv.fdata.size);
              if(recv.fdata.from+recv.fdata.size>=nBytesToReceive)
               {
                 df.Time = iReceiveFileTime;
                 df.Active = false;
                 ShowInfo("接收完成!");
               }
              ProgressBar1->Position = TBinFileFuncs::MakePercent(recv.fdata.from+recv.fdata.size,nBytesToReceive);
            }
           YbCommDevice1->WritePackage(&send,sizeof(TMyStatusPkg));
         }
      }
   }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
  if(iReceivingCounter>0)
   if(--iReceivingCounter==0)
    {
      if(df.Active)
       {
         df.Time = iReceiveFileTime;
         df.Active = false;
         ShowInfo("超时,接收中断。");
       }
    }
}
//---------------------------------------------------------------------------

⌨️ 快捷键说明

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