C++ Readfile操作完成,但用多条消息/串行通信填充数据缓冲区

C++ Readfile操作完成,但用多条消息/串行通信填充数据缓冲区,c++,serial-port,readfile,C++,Serial Port,Readfile,我正在开发一个应用程序,它可以读取串行端口上的数据。可以在短时间内通过此串行端口发送各种消息,读取传入数据的线程必须确定在ReadFile操作完成时读取的消息类型。我使用的是重叠结构,我希望消息能够一个接一个地被读取 我的问题是ReadFile操作经常用多条消息填充缓冲区,我找不到com超时值来阻止这种情况发生。我怀疑当背靠背接收到两条消息时,读取操作没有完成,这在读取线程中被视为一条消息,因为当第一条消息完成时,串行端口上仍然有数据 我用非重叠结构观察到了同样的现象 我使用的是串行com,配置

我正在开发一个应用程序,它可以读取串行端口上的数据。可以在短时间内通过此串行端口发送各种消息,读取传入数据的线程必须确定在ReadFile操作完成时读取的消息类型。我使用的是重叠结构,我希望消息能够一个接一个地被读取

我的问题是ReadFile操作经常用多条消息填充缓冲区,我找不到com超时值来阻止这种情况发生。我怀疑当背靠背接收到两条消息时,读取操作没有完成,这在读取线程中被视为一条消息,因为当第一条消息完成时,串行端口上仍然有数据

我用非重叠结构观察到了同样的现象

我使用的是串行com,配置如下:

    DCB configPort = { 0 };
    COMMTIMEOUTS timeouts;

    this->hDevice = CreateFileA(
            this->portReady,
            GENERIC_READ | GENERIC_WRITE,
            NULL,
            NULL,
            OPEN_EXISTING,
            FILE_FLAG_OVERLAPPED,
            NULL
    );

    if (this->hDevice == INVALID_HANDLE_VALUE) {
        std::cout << "INVALID HANDLE" << std::endl;
        return 0;
    }

    OvReception.Offset = 0;
    OvReception.OffsetHigh = 0;
    OvReception.hEvent = ::CreateEvent(NULL, FALSE, FALSE, _T("")); 

    configPort.DCBlength = sizeof(DCB);
    configPort.BaudRate = CBR_38400;
    configPort.StopBits = ONESTOPBIT;
    configPort.Parity = EVENPARITY;
    configPort.ByteSize = 8;
    configPort.fRtsControl = RTS_CONTROL_DISABLE;

    configPort.fAbortOnError = 0;
    configPort.XonLim = 800;
    configPort.XoffLim = 2000;

    timeouts.ReadIntervalTimeout = 1;
    timeouts.ReadTotalTimeoutMultiplier = 0;
    timeouts.ReadTotalTimeoutConstant = 0;
    timeouts.WriteTotalTimeoutMultiplier = 0;
    timeouts.WriteTotalTimeoutConstant = 0;

    if (!SetCommState(this->hDevice, &configPort)) {
        CloseHandle(this->hDevice);
        return 0;
    }

    if (!SetCommTimeouts(this->hDevice, &timeouts)) {
        CloseHandle(this->hDevice);
        return 0;
    }

DCB configPort={0};
通信超时;
此->hDevice=CreateFileA(
这个->portReady,
一般的读,一般的写,
无效的
无效的
开放式,
文件\u标志\u重叠,
无效的
);
如果(此->hDevice==无效的\u句柄\u值){
标准::cout hDevice);
返回0;
}
如果(!SetCommTimeouts(此->hDevice,&timeouts)){
CloseHandle(此->hDevice);
返回0;
}
我通过以下方式读取传入数据:


    bool readState = false;
    char incomingMessage[512] = {0};
    DWORD bytesRead = 0;
    memset(incomingMessage, 0, sizeof(incomingMessage));
    while (this->threadRunning) {

        readState = ReadFile(
            this->comSerie.hDevice,
            incomingMessage,
            sizeof(incomingMessage),
            NULL,
            &this->comSerie.OvReception);

        if (::GetLastError() == ERROR_IO_PENDING)
        {
            ::GetOverlappedResult(this->comSerie.hDevice, &this->comSerie.OvReception, &bytesRead, TRUE);
        }
        //NO ERRORS OBSERVED
        std::cout << "ERROR" << std::endl;
        std::cout << GetLastError() << std::endl;

        std::cout << "Message received" << std::endl;
        std::cout << incomingMessage<< std::endl;
        switch(ReceivedMessageType(incomingMessage)){
         //............ DO SOMETHING
        }
        //Clean buffer
        memset(incomingMessage, 0, sizeof(incomingMessage));
    }


bool readState=false;
char incomingMessage[512]={0};
DWORD字节读=0;
memset(incomingMessage,0,sizeof(incomingMessage));
同时(此->线程运行){
readState=ReadFile(
此->comSerie.hDevice,
输入消息,
sizeof(输入消息),
无效的
&这->comSerie.ovreceipt);
如果(::GetLastError()==错误\u IO\u挂起)
{
::GetOverlappedResult(this->comSerie.hDevice,&this->comSerie.ovreceivement,&bytesRead,TRUE);
}
//未发现任何错误

std::难道这是一种串行媒体,而不是消息媒体。如果你想要消息传递,你必须自己实现它,使用消息终止符,或长度词前缀,或XML之类的自描述协议。或只读取固定长度的固定长度消息。我看不出
WaitForSingleObject()
可能与此有关。你不能认真地想象Windows知道你的消息从哪里开始和停止,是吗?