开发者

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

Hey ppl

My question is how do i find out how many characters my ReadFile statement will return before calling the 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.

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?

#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. 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.

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.

Keep in mind that ReadFile() isn't perfect. I have experienced issues on slower hardware whereas ReadFile() does not always read in the complete message sent over the COM port. 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜