串口通信(文件传输)流控制

来源:互联网 发布:淘宝王者荣耀点券真假 编辑:程序博客网 时间:2024/03/28 20:19

出处:http://blog.sina.com.cn/s/blog_6c617ee30100u943.html


#include <afx.h>//send.cpp
#include <iostream>
#include <windows.h>
#include <process.h>
#include <string.h>
using namespace std;

HANDLE g_hCommDev=0;//串口句柄
HANDLE g_hEvent=0;
char filename[MAX_PATH];//文件名
char *wbuff;//指向输出缓冲区,后面new
FILE *wf;
DWORD z=0;//文件大小
void DiretorySearch(const char *dirPath);
void CommWatchProc(LPVOID pParam);
void CommLive(LPVOID pParam);
bool SetupSynCom()
{
 DCB dcb;
 COMMTIMEOUTS timeouts;
 if((g_hCommDev=CreateFile("COM1",GENERIC_WRITE,
  0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL))
  ==INVALID_HANDLE_VALUE)
  return false;
 timeouts.ReadIntervalTimeout=1000;
 timeouts.ReadTotalTimeoutConstant=1000;
 timeouts.ReadTotalTimeoutMultiplier=1000;
 timeouts.WriteTotalTimeoutConstant=1000;
 timeouts.WriteTotalTimeoutMultiplier=1000;
 SetCommTimeouts(g_hCommDev,&timeouts);
 SetupComm(g_hCommDev,1,102400);
 GetCommState(g_hCommDev,&dcb);
 dcb.BaudRate=CBR_115200 ;
 dcb.fParity=NOPARITY;
 dcb.ByteSize=8;
 dcb.StopBits=ONESTOPBIT;

 dcb.fOutxCtsFlow=true;
 dcb.fRtsControl=1;
SetCommState(g_hCommDev,&dcb);
 
 g_hEvent=CreateEvent(NULL,FALSE,true,"WatchEvevt");
 
 char pathName[MAX_PATH];
   char szPathTemp[MAX_PATH];
  GetModuleFileName(NULL, szPathTemp, MAX_PATH);
  for (int i=strlen(szPathTemp); i>=0; i--)
   
   if (szPathTemp[i] == '\\')
   {
    break;
   
   }
    szPathTemp[i]='\0';
  }
strcat(szPathTemp,"liuhansend.ini");
 CString myhere;
 ::GetPrivateProfileString("StudentInfo","Name",NULL,myhere.GetBuffer(MAX_PATH),MAX_PATH,szPathTemp);
 strcpy(pathName,myhere);
 cout<<"文件目录位于:"<<pathName<<endl;
 cout<<"配置文件位于"<<szPathTemp<<endl;
 _beginthread(&CommWatchProc,0,pathName);
 _beginthread(&CommLive,0,NULL);
 return true;
}

bool WriteComm(char *lpSneBuffer,DWORD dwBytesToWrite)
{
 bool bWriteState;
 DWORD dwBytesWritten=0;
 bWriteState=WriteFile(g_hCommDev,lpSneBuffer,dwBytesToWrite,
    &dwBytesWritten,NULL);
 z=z-(int)dwBytesWritten;
 cout<<"发送了"<<dwBytesWritten<<"字节数据,本次还剩"<<z<<"字节数据没有发送\n";
 if(!bWriteState || dwBytesWritten!=dwBytesToWrite)
 {
  cout<<"\n\n发送失败!"<<endl;
  Sleep(-1);
  return false;
 }
 else return true;
}
void CloseSynComm()
{

 SetCommMask(g_hCommDev,0);
 //WaitForSingleObject(hEvent,INFINITE);
 //CloseHandle(hEvent);
 PurgeComm(g_hCommDev,PURGE_TXCLEAR|PURGE_RXCLEAR);
 //CloseHandle(g_hCommDev);
}
void CommWatchProc(LPVOID pParam)
{
 char *p=(char *)pParam;
 wbuff=new char[102400];
 while(true)
 {

 DiretorySearch(p); 

 }
 delete wbuff;
}

void CommLive(LPVOID pParam)
{

 while(true){
 DWORD CTSUP=0;
 GetCommModemStatus(g_hCommDev,&CTSUP);
 if((CTSUP & MS_CTS_ON) != MS_CTS_ON)
 {
  cout<<"请检查串口线是否插好!\n";
  int i=0;
  for(;i<10;i++)
  CTSUP=0;
   GetCommModemStatus(g_hCommDev,&CTSUP);
   if((CTSUP & MS_CTS_ON) != MS_CTS_ON)
   
    Sleep(1000);
   }
   else break;
  }
  if(i>9)
  {
   cout<<"等待超时,请重启两边程序!\n";
   exit(0);
  }

 }
 else {
   Sleep(3000);
 }
 }
}

 //递归遍历指定文件夹下的所有文件夹和文件
 void DiretorySearch(const char *dirPath)
 

  WIN32_FIND_DATAA lpFindFileData;  
  char dirPathTemp[MAX_PATH];
  char dirCodeTemp[MAX_PATH];
  strcpy(dirPathTemp, dirPath);
  strcpy(dirCodeTemp, dirPath);
  const char *pChar = strrchr(dirPath, '\\');
  if(pChar != NULL && strlen(pChar) == 1)
   strcat(dirCodeTemp, "*");
    else
   {
   strcat(dirCodeTemp, "\\*");
   strcat(dirPathTemp, "\");
   }
  
  HANDLE handle = FindFirstFileA(dirCodeTemp, &lpFindFileData);
 if(handle == INVALID_HANDLE_VALUE)
  {
   cout<<dirPathTemp<<"检索失败!"<<endl;
   return;
  }
  
 if((lpFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) //判断文件属性
 {
  ZeroMemory(filename,MAX_PATH);
  strcpy(filename,dirPathTemp);
  int filelong=(lpFindFileData.nFileSizeHigh * (MAXDWORD+1) + lpFindFileData.nFileSizeLow);
  filename[strlen(filename)]='?';//文件名结束符,后面添加文件大小,好一起传输
  sprintf((filename+strlen(filename)),"%d",filelong);
  
  if(filelong==0)
  {
   if(remove(dirPathTemp)==0)    
    cout<<dirPathTemp<<"为空文件,直接删除了\n\n";
   
  }
  else{
   
   DWORD dwBytesWritten1=0;
   WriteFile(g_hCommDev,filename,MAX_PATH,
    &dwBytesWritten1,NULL);
   PurgeComm(g_hCommDev,PURGE_TXCLEAR|PURGE_RXCLEAR);//清空缓冲区
   Sleep(50);
   cout<<"准备传出文件:"<<filename<<endl;
   wf=fopen(dirPathTemp,"rb+");   
   z=filelong;
   ZeroMemory(wbuff,102400);
   if(z<=102400)
   {
    if(z>0)
    {
     fread(wbuff,z,1,wf);
     WriteComm(wbuff,z);
    }
    
   }
   else{
    fread(wbuff,102400,1,wf);
    WriteComm(wbuff,102400);
    
    
    while(true)
    {
     ZeroMemory(wbuff,102400);
     
     if(z<=102400)
     {
      if(z>0)
      {
       fread(wbuff,z,1,wf);
       WriteComm(wbuff,z);
      }
      break;
     }
     else{
      fread(wbuff,102400,1,wf);
      WriteComm(wbuff,102400);
     }
    }
    
   fclose(wf); 
   CloseSynComm();
   if(remove(dirPathTemp)==0)
    cout<<"成功发送并且删除文件:"<<dirPathTemp<<endl;
   else
   {cout<<dirPathTemp<<":文件没被删除!\n";
   cout<<"请手动删除该文件,并从新运行发送端和接收端程序!\n";
   Sleep(-1);
   }
  }
 }
 
 while (FindNextFileA(handle, &lpFindFileData))
 {
  if(!strcmp(lpFindFileData.cFileName, ".") || !strcmp(lpFindFileData.cFileName, ".."))
   continue;
  char dirFileTemp[MAX_PATH];
  strcpy(dirFileTemp, dirPathTemp);
  strcat(dirFileTemp, lpFindFileData.cFileName);
  if((lpFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY)
  {
   int filelong=(lpFindFileData.nFileSizeHigh * (MAXDWORD+1) + lpFindFileData.nFileSizeLow);
   if(filelong==0)
   {
    if(remove(dirFileTemp)==0)    
     cout<<dirFileTemp<<"为空文件,直接删除了\n\n";
    continue;
    }
    ZeroMemory(filename,MAX_PATH);
    strcpy(filename,dirFileTemp);
    filename[strlen(filename)]='?';
    sprintf((filename+(strlen(filename))),"%d",filelong);


    DWORD dwBytesWritten2=0;
    WriteFile(g_hCommDev,filename,MAX_PATH,
     &dwBytesWritten2,NULL);
                PurgeComm(g_hCommDev,PURGE_TXCLEAR|PURGE_RXCLEAR);
    Sleep(50);
    cout<<"准备传出文件:"<<filename<<endl;
    
    wf=fopen(dirFileTemp,"rb+");
    z=filelong;
    ZeroMemory(wbuff,102400);
    if(z<=102400)
    {
     if(z>0)
     {
      fread(wbuff,z,1,wf);
      WriteComm(wbuff,z);
     }
     
    }
    else{
     fread(wbuff,102400,1,wf);
     WriteComm(wbuff,102400);

     while(true)
     {
      ZeroMemory(wbuff,102400);
      
      if(z<=102400)
      {
       if(z>0)
       {
        fread(wbuff,z,1,wf);
        WriteComm(wbuff,z);
       }
       break;
      }
      else{
       fread(wbuff,102400,1,wf);
       WriteComm(wbuff,102400);
      }
     }
    }
    
    
    fclose(wf);
    CloseSynComm();
    //if(DeleteFile(dirFileTemp)!=0)
    if(remove(dirFileTemp)==0)
     cout<<dirFileTemp<<":成功发送并且删除文件\n\n";
    else
    {cout<<dirPathTemp<<":文件没被删除!\n";
    cout<<"请手动删除该文件,并从新运行发送端和接收端程序!\n";
    Sleep(-1);
    }
    
   }
   else
   {
    strcat(dirFileTemp, "\");
    //递归检查此子文件夹
    DiretorySearch(dirFileTemp);
   }
  }
  
  FindClose(handle);

}


int main()
{
 SetupSynCom(); 
Sleep(-1);
 return 0;
}

#include <afx.h>//recv.cpp
#include <iostream>
#include <io.h>
#include <direct.h>
#include <windows.h>
#include <time.h>
using namespace std;

HANDLE g_hCommDev=0;
HANDLE hEvent=0;
char *rbuff;
FILE *rf;

DWORD ReadComm(char *lpInBuffer,DWORD dwBytesToRead)
{
 DWORD dwBytesRead;
 if(!ReadFile(g_hCommDev,lpInBuffer,dwBytesToRead,&dwBytesRead,NULL))
  dwBytesRead=0;
 cout<<"收到"<<dwBytesRead<<"字节数据"<<endl;
 return dwBytesRead;
}


bool SetupSynCom()
{
 CString myhere6;
 char szPathTemp[MAX_PATH];
 GetModuleFileName(NULL, szPathTemp, MAX_PATH); 
 //取出文件路径  
 for (int i=strlen(szPathTemp); i>=0; i--)//strrchr()
  
  if (szPathTemp[i] == '\\')
  {
   break;  
  }
  szPathTemp[i]='\0';
 }

 strcat(szPathTemp,"liuhanrecv.ini");//打开当前目录的配置文件
 char filename[MAX_PATH];
 char filename2[MAX_PATH];
 ZeroMemory(filename2,MAX_PATH);
 ::GetPrivateProfileString("StudentInfo","Name",NULL,myhere6.GetBuffer(MAX_PATH),MAX_PATH,szPathTemp);
 cout<<"配置文件位于:"<<szPathTemp<<endl;
 strcpy(filename2,myhere6);
 char *ptr1=strrchr(filename2,'\\');
 if(strlen(ptr1)!=1)strcat(filename2,"\");
 cout<<"接受目录位于"<<filename2<<endl;
 DCB dcb;
 COMMTIMEOUTS timeouts;
 if((g_hCommDev=CreateFile("COM1",GENERIC_READ,
  0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL))
  ==INVALID_HANDLE_VALUE)
  
 {
  cout<< "com1口被占用!\n";
  return false;
 }
 timeouts.ReadIntervalTimeout=3000;
 timeouts.ReadTotalTimeoutConstant=3000;
 timeouts.ReadTotalTimeoutMultiplier=3000;
 timeouts.WriteTotalTimeoutConstant=1000;
 timeouts.WriteTotalTimeoutMultiplier=1000;
 SetCommTimeouts(g_hCommDev,&timeouts);
 SetupComm(g_hCommDev,10240,0);//设置接受缓冲区和输出缓冲区的大小。
 
 GetCommState(g_hCommDev,&dcb);
 dcb.BaudRate=CBR_115200 ;
 dcb.fParity=NOPARITY;
 dcb.ByteSize=8;
 dcb.StopBits=ONESTOPBIT;
 dcb.fRtsControl=1;
 dcb.fOutxCtsFlow=1;
 SetCommState(g_hCommDev,&dcb);

 SetCommMask(g_hCommDev,EV_ERR|EV_RXCHAR);

 hEvent=CreateEvent(NULL,FALSE,FALSE,"WatchEvevt");
 DWORD dwBytesRead0;
 //_beginthread(&CommWatchProc,0,NULL);
 DWORD dwEventMask=0,ModeStatus=0;
 
 int filelong=0;
 while(true)
 
   EscapeCommFunction(g_hCommDev,SETRTS);
   WaitCommEvent(g_hCommDev,&dwEventMask,NULL);
   if((dwEventMask & EV_RXCHAR)==EV_RXCHAR)
      char *filename0;
    filename0=new char[MAX_PATH];
    ZeroMemory(filename0,MAX_PATH); 
    ZeroMemory(filename,MAX_PATH); 
    strcpy(filename,filename2);
    dwBytesRead0=MAX_PATH;   
    ReadFile(g_hCommDev,filename0,MAX_PATH,&dwBytesRead0,NULL);//取文件名和文件大小
    strcat(filename,filename0+3);
    PurgeComm(g_hCommDev,PURGE_TXCLEAR|PURGE_RXCLEAR);
    delete []filename0;
    
   }
   else if((dwEventMask & EV_ERR)==EV_ERR)
   {
    cout<<"传输出错!请重起两边程序!\n";
   EscapeCommFunction(g_hCommDev,CLRRTS);
   exit(0);
   }
  
  SetEvent(hEvent);
  int namelen=strlen(filename);
  
  char *plong=NULL;
  for(int j=namelen;j>0;j--)
  {
   if(filename[j]=='?')
   {
    plong=&filename[j+1];
    filename[j]='\0';
    break;
   }
  }
  filelong=atoi(plong);//文件大小
  long handle;
  _finddata_t fileinfo;
  char *ptr=strrchr(filename,'\\');
  int dirlong=strlen(filename)-strlen(ptr); 
  char *dir=new char [dirlong+1];
  for(int x=3;x<=dirlong;x++)
  {
   if(filename[x]=='\\')
   
    ZeroMemory(dir,x+1);
    memcpy(dir,filename,x);
    handle=_findfirst(dir,&fileinfo);
    if(handle==-1)
    {
     _mkdir((const char*)dir);//目录不存在则新建
     cout<<"新建目录:"<<dir<<endl;
     _findclose(handle);
    }
   
   }
   
  }
  
  rf=fopen(filename,"wb+");
  delete []dir;
  rbuff=new char[102400];
  WaitCommEvent(g_hCommDev,&dwEventMask,NULL);
  if((dwEventMask & EV_RXCHAR)==EV_RXCHAR)
   
   int nTime = GetTickCount();
   int z=filelong;
   while(true)
   {
    ZeroMemory(rbuff,102400);
    if(z<=102400)
     
     ReadComm(rbuff,z);
     fwrite(rbuff,z,1,rf);
     fflush(rf);
     break;
       
    z-=ReadComm(rbuff,102400);
    fwrite(rbuff,102400,1,rf);
    fflush(rf);
   }
   cout<<"接收用的时间:"<<GetTickCount()-nTime<<"ms\n";
   cout<<"文件"<<filename<<"接收完毕!\n\n";
   EscapeCommFunction(g_hCommDev,CLRRTS);
  }
  if((dwEventMask & EV_ERR)==EV_ERR)
  {
   cout<<"传输出错!请重起两边程序!\n";
   EscapeCommFunction(g_hCommDev,CLRRTS);
   //rf=fopen(filename,"wb+");
   fclose(rf);
   remove(filename);
  exit(0);
  }
  
  fclose(rf);//接收一个文件结束。
  //WaitForSingleObject(hEvent,INFINITE);
  SetEvent(hEvent);
  delete []rbuff;
 
 return true;
}

 

int main()

 SetupSynCom();
 return 0;
}



0 0