简体   繁体   English

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

[英]ReadFile only reading one buffer character?

I'm writing a program to communicate to a motor drive through a virtual com port via USB.我正在编写一个程序,通过 USB 的虚拟 com 端口与电机驱动器进行通信。 I'm making use of the windows.h file-io to communicate with it (CreateFile, WriteFile, ReadFile).我正在使用 windows.h 文件 io 与其通信(CreateFile、WriteFile、ReadFile)。 I can write to the drive perfectly fine, but I run into an issue when trying to read from it.我可以完美地写入驱动器,但是在尝试读取驱动器时遇到了问题。 For some reason, the ReadFile only seems to read in one character from the buffer.出于某种原因, ReadFile 似乎只从缓冲区中读取一个字符。 Here's my code:这是我的代码:

#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 always seems to be set to 1. I'll get the first character that the drive outputs (an apostrophe), but it won't read the rest. dwRead 似乎总是设置为 1。我会得到驱动器输出的第一个字符(撇号),但不会读取其余的字符。 I've found some workarounds in that if I modify it to expect only one character and then loop through the reading, it will perform.我发现了一些解决方法,如果我将其修改为仅期望一个字符,然后循环读取,它将执行。
Additionally, I need the query the drive for a response, so before calling this ReadInput function, I have to call a WriteBuffer to send a character.此外,我需要查询驱动器以获得响应,因此在调用这个 ReadInput 函数之前,我必须调用一个 WriteBuffer 来发送一个字符。 If I put a delay (~10-50ms) between the read and write calls, it reads the whole thing.如果我在读取和写入调用之间设置延迟(~10-50 毫秒),它会读取整个内容。

Anyone have any ideas on this?有人对此有任何想法吗? It's not a huge issue since I've found some workarounds, but it has been bothering me for the past few days.这不是一个大问题,因为我找到了一些解决方法,但过去几天一直困扰着我。

Edit: Clarification for tinman's questions.编辑:澄清 tinman 的问题。

You need to call SetCommTimeouts with appropriate settings.您需要使用适当的设置调用SetCommTimeouts Here is some code that I use.这是我使用的一些代码。 You should look at the MSDN documentation for COMMTIMEOUTS structure.您应该查看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);

Of course you could also provide a total read timeout instead of an interval timeout.当然,您也可以提供总读取超时而不是间隔超时。

From MSDN : When reading from a communications device, the behavior of ReadFile is determined by the current communication time-out as set and retrieved by using the SetCommTimeouts and GetCommTimeouts functions.来自MSDN :从通信设备读取时, ReadFile的行为由设置的当前通信超时决定,并使用SetCommTimeoutsGetCommTimeouts函数检索。 Unpredictable results can occur if you fail to set the time-out values.如果未能设置超时值,可能会出现不可预测的结果。 For more information about communication time-outs, see COMMTIMEOUTS .有关通信超时的更多信息,请参阅COMMTIMEOUTS

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

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