串口ReadFile返回实际读取大小始终为0?解决思路
串口ReadFile返回实际读取大小始终为0?
VC6,异步,串口设备半双工
现在的一个应用就是向串口设备发送字符串命令,然后串口设备会返回一串结果,该结果长度可能在20~260之间,需要解析
可遇到一个问题,ReadFile的第三个参数(需要读取多长字节)小于串口设备实际返回长度的话,ReadFile函数返回的实际读取长度将是正确的(等于第三个参数的大小),若填260,则返回的实际读取长度始终为0,似乎是没完成260的额度ReadFile就无法读取串口返回数据了
串口读写上花费太多时间了,急死了,协议都没解析,已经耽误了事情
请大家帮我看看问题在哪里,顺便看看我的串口函数写得是不是有不合理的情况,我只能发56分的帖子倾囊发帖,非常感谢!!!
VC6,异步,串口设备半双工
现在的一个应用就是向串口设备发送字符串命令,然后串口设备会返回一串结果,该结果长度可能在20~260之间,需要解析
可遇到一个问题,ReadFile的第三个参数(需要读取多长字节)小于串口设备实际返回长度的话,ReadFile函数返回的实际读取长度将是正确的(等于第三个参数的大小),若填260,则返回的实际读取长度始终为0,似乎是没完成260的额度ReadFile就无法读取串口返回数据了
串口读写上花费太多时间了,急死了,协议都没解析,已经耽误了事情
请大家帮我看看问题在哪里,顺便看看我的串口函数写得是不是有不合理的情况,我只能发56分的帖子倾囊发帖,非常感谢!!!
- C/C++ code
// ***************************************打开串口 HANDLE OpenComm( LPCTSTR lpCommPort, UINT nBaudRate, UINT nParity, UINT nDataBits, UINT nStopBits) { HANDLE hComm = CreateFile( lpCommPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL ); if (hComm == INVALID_HANDLE_VALUE) return NULL; DCB dcb = {0}; dcb.DCBlength = sizeof(DCB); if (!GetCommState(hComm, &dcb)) { CloseComm(hComm); return NULL; } dcb.BaudRate = nBaudRate; dcb.fBinary = TRUE; dcb.fParity = nParity ? TRUE : FALSE; dcb.Parity = nParity; dcb.ByteSize = nDataBits; dcb.StopBits = nStopBits; if (!SetCommState(hComm, &dcb)) { CloseComm(hComm); return NULL; } return hComm; } // ***************************************读串口 BOOL ReadComm(HANDLE hComm, LPVOID lpBuf, DWORD nBufSize, LPDWORD lpReadSize) { if (hComm == NULL || hComm == INVALID_HANDLE_VALUE || lpBuf == NULL || nBufSize == 0) return FALSE; COMSTAT ComStat; DWORD dwErrorFlags; OVERLAPPED m_osRead; memset(&m_osRead,0,sizeof(OVERLAPPED)); // ******************WaitForSingleObject方式 m_osRead.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL); ClearCommError(hComm,&dwErrorFlags,&ComStat); if((DWORD)ComStat.cbInQue) return FALSE; BOOL bReadStatus; bReadStatus = ReadFile(hComm, lpBuf, nBufSize, lpReadSize, &m_osRead); if(!bReadStatus) { DWORD LASTERROR = GetLastError(); if(LASTERROR == ERROR_IO_PENDING) { // ******************WaitForSingleObject方式 DWORD dwWaitObj = WaitForSingleObject(m_osRead.hEvent, 3000); if(dwWaitObj == WAIT_OBJECT_0) { //问题就是: // ReadComm倒数第二个参数nBufSize为15(等比较小的数)时,可以进到这里,*lpReadSize将等于15 // 若填260,则dwWaitObj总是超时,此时即使不判断dwWaitObj依然查看m_osRead.InternalHigh值的话, // 该值始终始终为0 *lpReadSize = m_osRead.InternalHigh; if(*lpReadSize > 0) { int b = *lpReadSize; } bReadStatus = TRUE; } else { bReadStatus = FALSE; } // ******************GetOverlappedResult方式 //::GetOverlappedResult(hComm, &m_osRead, lpReadSize, TRUE); } else if(LASTERROR == NO_ERROR) { bReadStatus = TRUE; } else { bReadStatus = FALSE; } } PurgeComm(hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); return bReadStatus; } // ***************************************写串口 BOOL WriteComm(HANDLE hComm, LPCVOID lpBuf, DWORD nDataSize, LPDWORD lpWriteSize) { if (hComm == NULL || hComm == INVALID_HANDLE_VALUE || lpBuf == NULL || nDataSize == 0) return FALSE; DWORD dwErrorFlags; COMSTAT ComStat; OVERLAPPED m_osWrite; BOOL bWriteStat; memset(&m_osWrite,0,sizeof(OVERLAPPED)); // ******************WaitForSingleObject方式 m_osWrite.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL); ClearCommError(hComm, &dwErrorFlags, &ComStat); bWriteStat = WriteFile(hComm, lpBuf, nDataSize, lpWriteSize, &m_osWrite); if(!bWriteStat) { DWORD LASTERROR = GetLastError(); if(LASTERROR == ERROR_IO_PENDING) { // ******************WaitForSingleObject方式 DWORD dwWaitObj = WaitForSingleObject(m_osWrite.hEvent, 500); if(dwWaitObj == WAIT_OBJECT_0) { *lpWriteSize = m_osWrite.InternalHigh; bWriteStat = TRUE; } else { bWriteStat = FALSE; } // ******************GetOverlappedResult方式 //::GetOverlappedResult(hComm, &m_osWrite, lpWriteSize, TRUE); } else if(LASTERROR == NO_ERROR) { bWriteStat = TRUE; } else { bWriteStat = FALSE; } } PurgeComm(hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); return bWriteStat; } // ***************************************向串口写入命令并等待回复 BOOL SendGetComm(HANDLE hComm,LPBYTE lpByteCommand,DWORD dwCommandSize,BOOL bWantReturn,LPBYTE lpByteReturn, DWORD dwByteToRead,LPDWORD lpReturnSize) { DWORD dwSendCommandSize = 0; if (!WriteComm(hComm, lpByteCommand, dwCommandSize, (LPDWORD)&dwSendCommandSize)) { return FALSE; } if( dwSendCommandSize == dwCommandSize ) { if(bWantReturn) { if(!lpReturnSize || !lpByteReturn || dwByteToRead < 0) return FALSE; *lpReturnSize = 0; if (!ReadComm(hComm, lpByteReturn, dwByteToRead, lpReturnSize)) { return FALSE; } else { return TRUE; } } else { return TRUE; } } else { return FALSE; } } // 倒数第二个参数填15(等比较小的数)时,dwReadSize将大于0, // 若填260,dwReadSize始终为0, BYTE szReturn[260]; DWORD dwReadSize; return SendGetRWComm(m_hComm, lpCommandInfo, nCommandSize, TRUE, szReturn, 15, &dwReadSize);