在上位机和下位机通讯时,上位机发送一指令后想等待返回数据,自制了一数据接收函数,但调试时发现执行此函数时,如果接收缓冲区里没有数据则跳出函数,不进行等待。郁闷了。请高手指点我错在哪里,我想要在该程序里停止下来,直到接收缓冲区有数据并读出后返回。
void CFY3NO2View::GetDataFromCom()//接收8031发来的数据.   
{
    
    DWORD dwEvtMaskX;
    OVERLAPPED osRead;
    DWORD dwErrorFlags;
    COMSTAT ComStat;
    DWORD dwLength=0,NUM;
    BYTE abln;
    char adn[9];    osRead.Offset = 0;
    osRead.OffsetHigh = 0;
    
    osRead.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);    if(osRead.hEvent==NULL)
    {
        AfxMessageBox("建立事件失败!", MB_OK,  0 );    }
    if(!SetCommMask( COMFile,EV_RXCHAR))    
             dwEvtMaskX=0;
   WaitCommEvent( COMFile,&dwEvtMaskX,&osRead    );//本想在此等待,但如没有数据,  函数返回。如何才能留住CPU的脚步呢?
    if((dwEvtMaskX&EV_RXCHAR)==EV_RXCHAR)
        {  int i=0;
        
        do{
              ClearCommError( COMFile,&dwErrorFlags,&ComStat);
              dwLength=ComStat.cbInQue;
                
                
              if(dwLength>0)
               {
         
        ReadFile( COMFile,&abln,1,&NUM,&osRead);//
            
          GetComDate[i]=abln;
      
            }
            else  GetComDate[i]=11;
  i++;
            }while(dwLength>0);
             }
        
CloseHandle(osRead.hEvent);
}

解决方案 »

  1.   

    if ((dwEvtMask & EV_RXCHAR) == EV_RXCHAR)
    {
    ClearCommError(m_hFile, &dwErrorFlags, &ComStat);
    dwLen = min(ComStat.cbInQue, MAX_COM_MSG_LEN);
    dwLength = 0;
    BOOL bRead = ReadFile(m_hFile, (void*)m_pcRecvBuf, dwLen, &dwLength, &m_ReadOs);
    dwError = GetLastError(); if (dwLength && bRead && dwError==0){
    bSend = true;
    }
    if (!bRead && ERROR_IO_PENDING==dwError)
    {
    DWORD res = 0;
    while (!GetOverlappedResult(m_hFile,&m_ReadOs, &res, TRUE))
    {
    if (ERROR_IO_INCOMPLETE == GetLastError())
    dwLength += res;
    else
    {
    dwLength = 0;
    res = 0;
    break;
    }
    }
    dwLength += res;
    if (dwLength){
    }
    }
    else
    {
    ClearCommError(m_hFile,&dwErrorFlags,&ComStat ) ;
    }
    ...
    }
      

  2.   

    开一个单独的读数据线程:这个线程是一个死循环
    while(1)
    {
    BOOL bReadResult = ReadFile(pSerial->m_hCom, &byRxChar_Gprs,1, &dwLength_Gprs, NULL);
    //从串口读取数据
      if (bReadResult && (dwLength_Gprs > 0))
       {
        //有数据,处理
        //发消息
       }
       //没数据,循环
    }
    由于是线程,不影响其他处理
      

  3.   

    bSuccess = WaitCommEvent(m_hCom, &mask, &m_ovRead); if ( ! bSuccess )
    {
    int err = GetLastError(); if ( err == ERROR_IO_PENDING)
    {
    result = WaitForSingleObject(m_ovRead.hEvent, dwMaxWait);  //wait dwMaxWait
                                            // milli seconds before returning
    if ( result == WAIT_TIMEOUT )
    {
    // Handle the error.
    bSuccess = CloseHandle(m_ovRead.hEvent);
    ComAccess::ErrorToString("ReadData(): WaitForSingleObject() failed");
    return(-1);
    }
    }
    }

    // The specified event occured?

    if ( mask & EV_RXCHAR )
    {
                   ReadFile( COMFile,&abln,1,&NUM,&osRead);//以后按你的程序读文件就行了
              }
      

  4.   

    WaitCommEvent( COMFile,&dwEvtMaskX,&osRead    );
    调试时发现最后一个参数如果是&osRead,则在接收缓冲区没有数据的情况下直接返回了。没有等待的过程。返回0同时if ((dwEvtMask & EV_RXCHAR) == EV_RXCHAR)中的条件不满足。根本就不能执行IF下的程序。怎么回事呀。
    如果换成WaitCommEvent( COMFile,&dwEvtMaskX,NULL   );则等待。但在XP下,最后一个参数能为NULL吗?MSDN上说不行呀。
    /*lpOverlapped 
    Pointer to an OVERLAPPED structure. This structure is required if hFile was opened with FILE_FLAG_OVERLAPPED. 
    If hFile was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must not be NULL. It must point to a valid OVERLAPPED structure. If hFile was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the function can incorrectly report that the operation is complete. */