简体   繁体   English

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

[英]C++(Serial Communicatio using the <windows.h>) - How can i find out before hand, how many characters will be read by the ReadFile() method

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

Hey ppl 嘿ppl

My question is how do i find out how many characters my ReadFile statement will return before calling the ReadFile?. 我的问题是如何在调用ReadFile之前找出我的ReadFile语句将返回多少个字符? The device i am communicating with, returns different data based on what was sent. 我正在与之通信的设备根据发送的内容返回不同的数据。 Concerning the above ReadFile, in that instance i knew that the returned data would be 25 characters long, but what if i dont know the answer, how can i substitute 25 with a variable that will be enough for any amount of data received. 关于上面的ReadFile,在那种情况下,我知道返回的数据将是25个字符长,但是如果我不知道答案怎么办,我怎么能用一个足以容纳任何接收到的数据量的变量替代25。

In my code you will see i have 2 Readfile statements, in both cases i knew the amount of data i would receive, to i sent a fixed number, what happens when i dont know that amount? 在我的代码中,您将看到我有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...\n\n");

    //Displaying the buffer
    printf( "%s",buf);

    printf("\nData Read: %i\n",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: %i\n",dwBytesRead);
        printf("\n");
        printf("Enter an Option:");
        scanf("%c%c",&szRxChar,&trash);
    }

    CloseHandle(hSerial);// Closing the handle

    return 0;
}

You can't know what you are asking for, because no software can make predictions regarding the behaviour of a remote end. 您无法知道自己要什么,因为没有软件可以对远程终端的行为做出预测。 For this reason, the reading should take place in a different thread. 因此,读取应在其他线程中进行。 In the reading thread you can instruct ReadFile to read one byte at a time. 在读取线程中,您可以指示ReadFile一次读取一个字节。 You can choose to read more bytes at the same time, but then you are running the risk of having received a full message from the other part and still do not get a notification, because ReadFile is blocked waiting for more data. 您可以选择同时读取更多字节,但是这样会冒着从另一部分接收到完整消息的风险,但是仍然无法得到通知,因为ReadFile被阻止等待更多数据。

It may be challenging to create the threading code yourself. 自己创建线程代码可能很困难。 I recommend that you search for a library that already handles this for you. 我建议您搜索已经为您处理此问题的库。

You won't ever know exactly what was sent, but instead of putting 25 , use sizeof(buffer) instead. 您将永远不会确切知道发送了什么,而是使用sizeof(buffer)而不是25

Keep in mind that ReadFile() isn't perfect. 请记住, ReadFile()并不完美。 I have experienced issues on slower hardware whereas ReadFile() does not always read in the complete message sent over the COM port. 我在较慢的硬件上遇到了问题,而ReadFile()并不总是读取通过COM端口发送的完整消息。 Therefore, it may be beneficial to read in byte-by-byte, albeit slower, to ensure you get the entire message: 因此,最好逐个字节读取,尽管速度较慢,以确保获得完整的消息:

 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;
     }
}

in the example above, keyBuf is a private class variable and the above code is part of a function that is called in a while loop. 在上面的示例中, keyBuf是私有类变量,上面的代码是在while循环中调用的函数的一部分。

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

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