繁体   English   中英

ReadFile 只读取一个缓冲区字符?

[英]ReadFile only reading one buffer character?

我正在编写一个程序,通过 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<<"a\n";PrintInput(lpBuf,dwRead);}
    }

    if(fWaitingOnRead){
        dwRes = WaitForSingleObject(osReader.hEvent,READ_TIMEOUT);
        cout<<"\n\nAfter WaitForSingleObject."<<endl;
        switch(dwRes)
        {
        case WAIT_OBJECT_0:
            if(!GetOverlappedResult(hComm,&osReader,&dwRead,TRUE))
                cout<<"Error in Comm"<<endl;
            else
                {cout<<"b\n\n";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-50 毫秒),它会读取整个内容。

有人对此有任何想法吗? 这不是一个大问题,因为我找到了一些解决方法,但过去几天一直困扰着我。

编辑:澄清 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM