C++(使用 <windows.h> 的串行通信) - 我如何事先知道 ReadFile() 方法将读取多少个字符



ReadFile(hSerial, buffer, 25, &dwBytesRead, 0);

嘿ppl

我的问题是我如何发现我的ReadFile语句在调用ReadFile之前将返回多少字符?我正在与之通信的设备,根据发送的内容返回不同的数据。关于上面的ReadFile,在那个实例中,我知道返回的数据将是25个字符长,但是如果我不知道答案,我怎么能用一个足以接收任何数据量的变量代替25呢?

在我的代码中,你会看到我有2个Readfile语句,在这两种情况下,我都知道我将收到的数据量,我发送了一个固定的数字,当我不知道这个数量时会发生什么?

#include "stdafx.h"
#include "windows.h"
BOOL SetCommDefaults(HANDLE hSerial);
void StripCRLFandPrint(char *command);
char buffer[1000];
HANDLE hSerial;
DWORD dwBytesRead = 0;
DWORD dwBytesWritten = 0;
char trash;
int main(int argc, char* argv[])
{
    hSerial = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0 , 0 , OPEN_EXISTING , 0 , 0);
    if (hSerial == INVALID_HANDLE_VALUE) return GetLastError();
    SetCommDefaults(hSerial);//Initializing the Device Control Block
    COMMTIMEOUTS timeouts={0};
    timeouts.ReadIntervalTimeout=50;
    timeouts.ReadTotalTimeoutConstant=50;
    timeouts.ReadTotalTimeoutMultiplier=10;
    timeouts.WriteTotalTimeoutConstant=50;
    timeouts.WriteTotalTimeoutMultiplier=10;
    char szRxChar[3];//varialble holds characters that will be sent
    szRxChar[0] = '?';
    DWORD y =0, z =0;
    char buf[327];// will hold the data received 
    memset(buf,0,327);//initializing the buf[]
    memset(buffer,0,10000);
    WriteFile( hSerial , &szRxChar , 1, &dwBytesWritten ,0);
    ReadFile( hSerial ,  buf , sizeof(buf), &dwBytesRead , 0);
    printf("Retrieving data...nn");
    //Displaying the buffer
    printf( "%s",buf);
    printf("nData Read: %in",dwBytesRead);
    printf("Enter an option:");
    scanf("%c%c",&szRxChar,&trash);//Reading the next command to be sent
    while(szRxChar[0] != '1')//Press one to exit
    {
        memset(buffer,0,10000);
        //StripCRLFandPrint(szRxChar);
        WriteFile( hSerial , &szRxChar, 1, &dwBytesWritten ,0);
        ReadFile( hSerial ,  buffer , 25, &dwBytesRead , 0);
        printf("%s",buffer);
        printf("nData Read: %in",dwBytesRead);
        printf("n");
        printf("Enter an Option:");
        scanf("%c%c",&szRxChar,&trash);
    }
    CloseHandle(hSerial);// Closing the handle
    return 0;
}

你不知道你在要求什么,因为没有软件可以预测远程端的行为。由于这个原因,读取应该在不同的线程中进行。在读取线程中,你可以指示ReadFile每次读取一个字节。你可以选择同时读取更多的字节,但这样你就有可能从另一部分收到完整的消息,但仍然没有收到通知,因为ReadFile被阻塞等待更多的数据。

自己创建线程代码可能具有挑战性。我建议您搜索已经为您处理此问题的库。

您永远不会确切知道发送的是什么,但不要使用25,而是使用sizeof(buffer)

请记住,ReadFile()不是完美的。我在较慢的硬件上遇到过问题,而ReadFile()并不总是读取通过COM端口发送的完整消息。因此,逐字节读取可能是有益的,尽管速度较慢,但可以确保获得整个消息:

 int c;
 DWORD dwBytesRead = 0;
 if (!(pcState[readerPort] & PORT_OPEN)) {
    RecvIndex = 0;
    Sleep(1000);
    return;
 }
 ReadFile(hComm[readerPort], buff, 1, &dwBytesRead, NULL); // array of handles used here
 c = buff[0];

 if (dwBytesRead == 0) {  // possible end of transmission
    if (RecvTimer++ > 3) {
        RecvTimer = 0;
        if (RecvIndex) {      // have receive some data prior
            keyBuf[RecvIndex] = 0;
            RecvIndex = 0;
            processBuffer(keyBuf);
            memset(keyBuf, 0, sizeof(keyBuf));      
        }
    }
} else {
    RecvTimer = 0;  //Restart timer
    if (RecvIndex == 0) { // first character
        memset(keyBuf, 0, sizeof(keyBuf));
        keyBuf[0] = (unsigned char)c;
        RecvIndex = 1;
     } else {        // get remaining characters
        if (RecvIndex < sizeof(keyBuf))     
            keyBuf[RecvIndex++] = (unsigned char)c;
     }
}
在上面的例子中,keyBuf是一个私有类变量,上面的代码是while循环中调用的函数的一部分。

最新更新