ReadFile只读取一个缓冲区字符



我正在编写一个程序,通过USB通过虚拟com端口与电机驱动器通信。我正在利用windows.h文件-io与它通信(CreateFile, WriteFile, ReadFile)。我可以完全写入驱动器,但我遇到了一个问题,当我试图从它读取。由于某种原因,ReadFile似乎只从缓冲区中读入一个字符。下面是我的代码:

#define READ_BUFF_SIZE 500
#define READ_TIMEOUT 5000
void ReadInput(HANDLE hComm)
{
    DWORD dwRead, dwRes;
    BOOL fWaitingOnRead = FALSE;
    OVERLAPPED osReader = {0};
    char lpBuf[READ_BUFF_SIZE] = {0};
    osReader.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
    if(osReader.hEvent==NULL){
        cerr<<"Error creating overlapped handle!";return;}
    if(!fWaitingOnRead){
        if(!ReadFile(hComm, lpBuf, READ_BUFF_SIZE, &dwRead, &osReader)){
            if(GetLastError()!=ERROR_IO_PENDING)
                {cout<<"Error: "<<GetLastError()<<endl;return;}
            else
                fWaitingOnRead = TRUE;
        }
        else {cout<<"an";PrintInput(lpBuf,dwRead);}
    }
    if(fWaitingOnRead){
        dwRes = WaitForSingleObject(osReader.hEvent,READ_TIMEOUT);
        cout<<"nnAfter WaitForSingleObject."<<endl;
        switch(dwRes)
        {
        case WAIT_OBJECT_0:
            if(!GetOverlappedResult(hComm,&osReader,&dwRead,TRUE))
                cout<<"Error in Comm"<<endl;
            else
                {cout<<"bnn";PrintInput(lpBuf,dwRead);}
            fWaitingOnRead = FALSE;
            break;
        case WAIT_TIMEOUT:
            cout<<"wait timeout"<<endl;
            break;
        default:
            cout<<"Default Case"<<endl;
            break;
        }
    }
}

dwRead似乎总是被设置为1。我将获得驱动器输出的第一个字符(撇号),但它不会读取其余的字符。我发现了一些变通方法,如果我修改它,只期望一个字符,然后循环通过读取,它将执行。
此外,我需要查询驱动器以获得响应,因此在调用ReadInput函数之前,我必须调用WriteBuffer来发送一个字符。如果我在读和写调用之间设置一个延迟(~10-50ms),它就会读取整个内容。

有人有什么想法吗?这不是一个大问题,因为我已经找到了一些变通办法,但它一直困扰着我在过去的几天。

编辑:澄清tinman的问题。

您需要调用具有适当设置的SetCommTimeouts。这里是我使用的一些代码。您应该查看COMMTIMEOUTS结构的MSDN文档。

// Only use read interval timeout. Do not use total read/write timeout.
COMMTIMEOUTS commtimeouts = { min((1000 + GetBaudrate() - 1) / GetBaudrate(), 1), 0, 0, 0, 0 };
SetCommTimeouts(m_hFile, &commtimeouts);

当然,你也可以提供一个总的读超时,而不是一个间隔超时。

来自MSDN:当从通信设备读取时,ReadFile的行为由当前通信超时确定,并通过使用SetCommTimeoutsGetCommTimeouts函数检索。如果未能设置超时值,可能会出现不可预测的结果。有关通信超时的详细信息,请参见COMMTIMEOUTS

相关内容

最新更新