简体   繁体   中英

serial port connection - ReadFile always return 4 bytes read

I'm trying to read by ReadFile but always get that its read 4 bytes, doesn't mutter how long was the string.

UART* uart = (UART*)lpParam;
char TempChar; //Temporary character used for reading
char SerialBuffer[256];//Buffer for storing Rxed Data
DWORD NoBytesRead;
int i = 0;

do
{
    NoBytesRead = 0;
    ReadFile(uart->connHandle,           //Handle of the Serial port
        &SerialBuffer,       //Temporary character
        sizeof(256),//Size of TempChar
        &NoBytesRead,    //Number of bytes read
        NULL);

    //SerialBuffer[i] = TempChar;// Store Tempchar into buffer
    i++;
    if (NoBytesRead > 0)
    {
        char* strMsg = (char*)malloc(sizeof(256 * sizeof(char)));
        SerialBuffer[NoBytesRead] = '\0';
        TRACE("read %d- %s\n", NoBytesRead,SerialBuffer);
        strcpy_s(strMsg, 256,SerialBuffer);
        ControllerPublishMsg(uart->controller, SerialBuffer);
    }
    SerialBuffer[0] = '\0';

In case i send string "hh" to connection I'm get output "read 4- hh". The string is 2 bytes long, but NoBytesRead = 4.

thanks.

sizeof(256) defaults to sizeof(int) this is four bytes. replace sizeof(256) by 256 . Also replace sizeof(256 * sizeof(char)) by (256 * sizeof(char)) .

Think about the statement

sizeof(256)

that you pass as a buffer size.

That expression evaluates to the same thing as

sizeof(int)

which probably evaluates to 4 on your platform. You'd need to hand over the literal value 256 or better sizeof SerialBuffer to ReadFile .

And you got the same error in your malloc arguments.

Why you are receiving 4 characters when you (think you) are sending only 2 is impossible to see without the code on the sender side. In case ReadFile returns 4, it most probably received 4 characters. Due to the messed up buffer size argument, it will however not be able to receive more than 4 characters .

You are misusing sizeof .

When calling ReadFile() , you are using sizeof(256) as the number of bytes to read. A numeric literal is an int by default, so you are really using sizeof(int) , which is 4 bytes on your compiler. Get rid of the sizeof and just use 256 by itself:

ReadFile(uart->connHandle,           //Handle of the Serial port
    &SerialBuffer,       //Temporary character
    256,//Size of TempChar
    &NoBytesRead,    //Number of bytes read
    NULL);

Or better, get rid of the 256 and use sizeof(SerialBuffer) instead, since it is a static array with a fixed size known at compile time:

ReadFile(uart->connHandle,           //Handle of the Serial port
    &SerialBuffer,       //Temporary character
    sizeof(SerialBuffer),//Size of TempChar
    &NoBytesRead,    //Number of bytes read
    NULL);

You are making a similar mistake when calling malloc() . sizeof(char) is always 1, so you are really calling sizeof(256) again. So again, you can get rid of sizeof and just use 256 by itself:

char* strMsg = (char*) malloc(256 * sizeof(char));
// or just: char* strMsg = (char*) malloc(256);

Although, you are not actually using strMsg for anything (and you are leaking it), so you should just get rid of it completely.

Try something more like this:

UART* uart = (UART*)lpParam;
char SerialBuffer[257];//Buffer for storing Rxed Data
DWORD NoBytesRead;

do
{
    NoBytesRead = 0;
    ReadFile(uart->connHandle, //Handle of the Serial port
        SerialBuffer, //Temporary buffer
        sizeof(SerialBuffer)-1,//Size of buffer minus null-terminator
        &NoBytesRead, //Number of bytes read
        NULL);

    if (NoBytesRead > 0)
    {
        SerialBuffer[NoBytesRead] = '\0';
        TRACE("read %u- %s\n", NoBytesRead, SerialBuffer);
        ControllerPublishMsg(uart->controller, SerialBuffer);
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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