在上位机和下位机通讯时,上位机发送一指令后想等待返回数据,自制了一数据接收函数,但调试时发现执行此函数时,如果接收缓冲区里没有数据则跳出函数,不进行等待。郁闷了。请高手指点我错在哪里,我想要在该程序里停止下来,直到接收缓冲区有数据并读出后返回。
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);
}
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);
}
{
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 ) ;
}
...
}
while(1)
{
BOOL bReadResult = ReadFile(pSerial->m_hCom, &byRxChar_Gprs,1, &dwLength_Gprs, NULL);
//从串口读取数据
if (bReadResult && (dwLength_Gprs > 0))
{
//有数据,处理
//发消息
}
//没数据,循环
}
由于是线程,不影响其他处理
{
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);//以后按你的程序读文件就行了
}
调试时发现最后一个参数如果是&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. */