Clearing buffer while reading in binary data from a server in C++












0















I have a server that sends raw binary data to print a "map" that a user must traverse through, however, I am having trouble clearing out my buffer after each line read and thus keep getting residual data printed at the end of the shorter lines. In the screenshot below you can see my output on the left, and what the output should be on the right. What is the best way to solve this? I feel like I am missing something but cant seem to find a solution.



enter image description here



And the code that is reading/printing this is below:



char* mapData = NULL;
string command = "command> ";
size_t dataSize = 0;
while(mapData != command.c_str()) {
unsigned char* buffer = (unsigned char*) &dataSize;
connection = read(mySocket, buffer, 8);
if(connection == -1 || connection < 0) {
cerr << "**Error: could not read text size" << endl;
return 1;
}

mapData = (char*)malloc(dataSize);
buffer = (unsigned char*) mapData;

while((connection = read(mySocket, buffer, dataSize)) != -1) {
if(connection == -1 || connection < 0) {
cerr << "**Error: could not read text size" << endl;
return 1;
}
if(dataSize != 1) {
cout << buffer;
}
free(buffer);
buffer = NULL;
}

}









share|improve this question


















  • 5





    Is it possible that the inner while loop iterates more than once? If so, freeing buffer inside that loop is almost definitely incorrect.

    – eozd
    Nov 24 '18 at 14:50






  • 2





    On a couple of unrelated notes: You don't need the buffer variable. Pass &dataSize directly to the read call. Also pass sizeof dataSize instead of hard-coding 8. And don't forget that read will return 0 if the socket is close, something you need to handle as well. Lastly, if you use TCP sockets, then a single read call may return less than what was written, you need to call read in a loop until all requested data has been received.

    – Some programmer dude
    Nov 24 '18 at 14:53






  • 2





    Use the return value from read which is the number of bytes.

    – stark
    Nov 24 '18 at 16:34
















0















I have a server that sends raw binary data to print a "map" that a user must traverse through, however, I am having trouble clearing out my buffer after each line read and thus keep getting residual data printed at the end of the shorter lines. In the screenshot below you can see my output on the left, and what the output should be on the right. What is the best way to solve this? I feel like I am missing something but cant seem to find a solution.



enter image description here



And the code that is reading/printing this is below:



char* mapData = NULL;
string command = "command> ";
size_t dataSize = 0;
while(mapData != command.c_str()) {
unsigned char* buffer = (unsigned char*) &dataSize;
connection = read(mySocket, buffer, 8);
if(connection == -1 || connection < 0) {
cerr << "**Error: could not read text size" << endl;
return 1;
}

mapData = (char*)malloc(dataSize);
buffer = (unsigned char*) mapData;

while((connection = read(mySocket, buffer, dataSize)) != -1) {
if(connection == -1 || connection < 0) {
cerr << "**Error: could not read text size" << endl;
return 1;
}
if(dataSize != 1) {
cout << buffer;
}
free(buffer);
buffer = NULL;
}

}









share|improve this question


















  • 5





    Is it possible that the inner while loop iterates more than once? If so, freeing buffer inside that loop is almost definitely incorrect.

    – eozd
    Nov 24 '18 at 14:50






  • 2





    On a couple of unrelated notes: You don't need the buffer variable. Pass &dataSize directly to the read call. Also pass sizeof dataSize instead of hard-coding 8. And don't forget that read will return 0 if the socket is close, something you need to handle as well. Lastly, if you use TCP sockets, then a single read call may return less than what was written, you need to call read in a loop until all requested data has been received.

    – Some programmer dude
    Nov 24 '18 at 14:53






  • 2





    Use the return value from read which is the number of bytes.

    – stark
    Nov 24 '18 at 16:34














0












0








0








I have a server that sends raw binary data to print a "map" that a user must traverse through, however, I am having trouble clearing out my buffer after each line read and thus keep getting residual data printed at the end of the shorter lines. In the screenshot below you can see my output on the left, and what the output should be on the right. What is the best way to solve this? I feel like I am missing something but cant seem to find a solution.



enter image description here



And the code that is reading/printing this is below:



char* mapData = NULL;
string command = "command> ";
size_t dataSize = 0;
while(mapData != command.c_str()) {
unsigned char* buffer = (unsigned char*) &dataSize;
connection = read(mySocket, buffer, 8);
if(connection == -1 || connection < 0) {
cerr << "**Error: could not read text size" << endl;
return 1;
}

mapData = (char*)malloc(dataSize);
buffer = (unsigned char*) mapData;

while((connection = read(mySocket, buffer, dataSize)) != -1) {
if(connection == -1 || connection < 0) {
cerr << "**Error: could not read text size" << endl;
return 1;
}
if(dataSize != 1) {
cout << buffer;
}
free(buffer);
buffer = NULL;
}

}









share|improve this question














I have a server that sends raw binary data to print a "map" that a user must traverse through, however, I am having trouble clearing out my buffer after each line read and thus keep getting residual data printed at the end of the shorter lines. In the screenshot below you can see my output on the left, and what the output should be on the right. What is the best way to solve this? I feel like I am missing something but cant seem to find a solution.



enter image description here



And the code that is reading/printing this is below:



char* mapData = NULL;
string command = "command> ";
size_t dataSize = 0;
while(mapData != command.c_str()) {
unsigned char* buffer = (unsigned char*) &dataSize;
connection = read(mySocket, buffer, 8);
if(connection == -1 || connection < 0) {
cerr << "**Error: could not read text size" << endl;
return 1;
}

mapData = (char*)malloc(dataSize);
buffer = (unsigned char*) mapData;

while((connection = read(mySocket, buffer, dataSize)) != -1) {
if(connection == -1 || connection < 0) {
cerr << "**Error: could not read text size" << endl;
return 1;
}
if(dataSize != 1) {
cout << buffer;
}
free(buffer);
buffer = NULL;
}

}






c++ server binary-data datareader






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 24 '18 at 14:46









ejscribnerejscribner

515




515








  • 5





    Is it possible that the inner while loop iterates more than once? If so, freeing buffer inside that loop is almost definitely incorrect.

    – eozd
    Nov 24 '18 at 14:50






  • 2





    On a couple of unrelated notes: You don't need the buffer variable. Pass &dataSize directly to the read call. Also pass sizeof dataSize instead of hard-coding 8. And don't forget that read will return 0 if the socket is close, something you need to handle as well. Lastly, if you use TCP sockets, then a single read call may return less than what was written, you need to call read in a loop until all requested data has been received.

    – Some programmer dude
    Nov 24 '18 at 14:53






  • 2





    Use the return value from read which is the number of bytes.

    – stark
    Nov 24 '18 at 16:34














  • 5





    Is it possible that the inner while loop iterates more than once? If so, freeing buffer inside that loop is almost definitely incorrect.

    – eozd
    Nov 24 '18 at 14:50






  • 2





    On a couple of unrelated notes: You don't need the buffer variable. Pass &dataSize directly to the read call. Also pass sizeof dataSize instead of hard-coding 8. And don't forget that read will return 0 if the socket is close, something you need to handle as well. Lastly, if you use TCP sockets, then a single read call may return less than what was written, you need to call read in a loop until all requested data has been received.

    – Some programmer dude
    Nov 24 '18 at 14:53






  • 2





    Use the return value from read which is the number of bytes.

    – stark
    Nov 24 '18 at 16:34








5




5





Is it possible that the inner while loop iterates more than once? If so, freeing buffer inside that loop is almost definitely incorrect.

– eozd
Nov 24 '18 at 14:50





Is it possible that the inner while loop iterates more than once? If so, freeing buffer inside that loop is almost definitely incorrect.

– eozd
Nov 24 '18 at 14:50




2




2





On a couple of unrelated notes: You don't need the buffer variable. Pass &dataSize directly to the read call. Also pass sizeof dataSize instead of hard-coding 8. And don't forget that read will return 0 if the socket is close, something you need to handle as well. Lastly, if you use TCP sockets, then a single read call may return less than what was written, you need to call read in a loop until all requested data has been received.

– Some programmer dude
Nov 24 '18 at 14:53





On a couple of unrelated notes: You don't need the buffer variable. Pass &dataSize directly to the read call. Also pass sizeof dataSize instead of hard-coding 8. And don't forget that read will return 0 if the socket is close, something you need to handle as well. Lastly, if you use TCP sockets, then a single read call may return less than what was written, you need to call read in a loop until all requested data has been received.

– Some programmer dude
Nov 24 '18 at 14:53




2




2





Use the return value from read which is the number of bytes.

– stark
Nov 24 '18 at 16:34





Use the return value from read which is the number of bytes.

– stark
Nov 24 '18 at 16:34












3 Answers
3






active

oldest

votes


















2














You are ignoring the return value of read() to know how many bytes are in the buffer.



read() returns the actual number of bytes that were read, which may be fewer than you requested. So you need to call read() in a loop until you have read all of the bytes you are expecting, eg:



int readAll(int sock, void *buffer, size_t buflen)
{
unsigned char* pbuf = reinterpret_cast<unsigned char*>(buffer);
while (buflen > 0) {
int numRead = read(sock, pbuf, buflen);
if (numRead < 0) return -1;
if (numRead == 0) return 0;
pbuf += numRead;
buflen -= numRead;
}
return 1;
}


Also, after reading the buffer, you are treating it as if it were null-terminated, but it is not, which is why you get extra garbage in your output.



More importantly, mapData != command.c_str() will ALWAYS be true, so your while loop iterates indefinitely (until a socket error occurs), which is not what you want. You want the loop to end when you receive a "command> " string instead.



mapData is initially NULL, and c_str() NEVER returns NULL, so the loop ALWAYS iterates at least once.



Then you allocate and free mapData but don't reset it to NULL, so it is left pointing at invalid memory. Which doesn't really matter, since your while loop is just comparing pointers. c_str() will NEVER return a pointer to memory that mapData ever points to.



To end your loop correctly, you need to compare the contents of mapData after reading, not compare its memory address.



Try this instead:



char *mapData = NULL;
uint64_t dataSize = 0;
const string command = "command> ";
bool keepLooping = true;

do {
if (readAll(mySocket, &dataSize, sizeof(dataSize)) <= 0) {
cerr << "**Error: could not read text size" << endl;
return 1;
}

if (dataSize == 0)
continue;

mapData = new char[dataSize];

if (readAll(mySocket, mapData, dataSize) <= 0) {
cerr << "**Error: could not read text" << endl;
delete mapData;
return 1;
}

cout.write(mapData, dataSize);

keepLooping = (dataSize != command.size()) || (strncmp(mapData, command.c_str(), command.size()) != 0);

delete mapData;
}
while (keepLooping);


Alternatively:



string mapData;
uint64_t dataSize = 0;
const string command = "command> ";

do {
if (readAll(mySocket, &dataSize, sizeof(dataSize)) <= 0) {
cerr << "**Error: could not read text size" << endl;
return 1;
}

mapData.resize(dataSize);

if (dataSize > 0) {
if (readAll(mySocket, &mapData[0], dataSize) <= 0) {
cerr << "**Error: could not read text" << endl;
return 1;
}

cout << mapData;
}
}
while (mapData != command);





share|improve this answer


























  • Worked perfectly! Only issue is its not printing out the "command> " itself but a little messing around should fix that. Thank you!

    – ejscribner
    Nov 25 '18 at 21:17











  • @ejscribner it should be printing out everything that is received. However, cout is usually buffered, so you may need to flush it once the command has been received, via cout << flush or cout.flush()

    – Remy Lebeau
    Nov 26 '18 at 1:39





















1














like @eozd pointed out, calling malloc and free in your loop is a bad idea since you use return statements. Your code may leak memory. You should ensure you call free before returns. Even better, you could declare your buffer outside of while loop, and use break instead of return, and call free if there was en error



Looking at your solution, it seems that the communication protocol involves sending data size first, followed by the actual data. How is data size written to the wire? You may need to convert it from network byte order.



To debug, you could print out the value of dataSize before every read to make sure that it is what you expect






share|improve this answer
























  • Before each line of actual data, it sends a size_t that represents how many bytes need to be read, however when I print the dataSize it prints the proper size (18 for line 1, then 10 for the rest of the lines) but still leaves the 'Miffy!' at the end of each of the remaining shorter lines.

    – ejscribner
    Nov 24 '18 at 17:07











  • what happens if you put memset(buffer, 0, datasize); right before free(buffer)?

    – HappyKeyboard
    Nov 24 '18 at 17:35



















0














You should clear the buffer too. Add:



 memset(mapData, 0, dataSize);


after the malloc.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53459312%2fclearing-buffer-while-reading-in-binary-data-from-a-server-in-c%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    2














    You are ignoring the return value of read() to know how many bytes are in the buffer.



    read() returns the actual number of bytes that were read, which may be fewer than you requested. So you need to call read() in a loop until you have read all of the bytes you are expecting, eg:



    int readAll(int sock, void *buffer, size_t buflen)
    {
    unsigned char* pbuf = reinterpret_cast<unsigned char*>(buffer);
    while (buflen > 0) {
    int numRead = read(sock, pbuf, buflen);
    if (numRead < 0) return -1;
    if (numRead == 0) return 0;
    pbuf += numRead;
    buflen -= numRead;
    }
    return 1;
    }


    Also, after reading the buffer, you are treating it as if it were null-terminated, but it is not, which is why you get extra garbage in your output.



    More importantly, mapData != command.c_str() will ALWAYS be true, so your while loop iterates indefinitely (until a socket error occurs), which is not what you want. You want the loop to end when you receive a "command> " string instead.



    mapData is initially NULL, and c_str() NEVER returns NULL, so the loop ALWAYS iterates at least once.



    Then you allocate and free mapData but don't reset it to NULL, so it is left pointing at invalid memory. Which doesn't really matter, since your while loop is just comparing pointers. c_str() will NEVER return a pointer to memory that mapData ever points to.



    To end your loop correctly, you need to compare the contents of mapData after reading, not compare its memory address.



    Try this instead:



    char *mapData = NULL;
    uint64_t dataSize = 0;
    const string command = "command> ";
    bool keepLooping = true;

    do {
    if (readAll(mySocket, &dataSize, sizeof(dataSize)) <= 0) {
    cerr << "**Error: could not read text size" << endl;
    return 1;
    }

    if (dataSize == 0)
    continue;

    mapData = new char[dataSize];

    if (readAll(mySocket, mapData, dataSize) <= 0) {
    cerr << "**Error: could not read text" << endl;
    delete mapData;
    return 1;
    }

    cout.write(mapData, dataSize);

    keepLooping = (dataSize != command.size()) || (strncmp(mapData, command.c_str(), command.size()) != 0);

    delete mapData;
    }
    while (keepLooping);


    Alternatively:



    string mapData;
    uint64_t dataSize = 0;
    const string command = "command> ";

    do {
    if (readAll(mySocket, &dataSize, sizeof(dataSize)) <= 0) {
    cerr << "**Error: could not read text size" << endl;
    return 1;
    }

    mapData.resize(dataSize);

    if (dataSize > 0) {
    if (readAll(mySocket, &mapData[0], dataSize) <= 0) {
    cerr << "**Error: could not read text" << endl;
    return 1;
    }

    cout << mapData;
    }
    }
    while (mapData != command);





    share|improve this answer


























    • Worked perfectly! Only issue is its not printing out the "command> " itself but a little messing around should fix that. Thank you!

      – ejscribner
      Nov 25 '18 at 21:17











    • @ejscribner it should be printing out everything that is received. However, cout is usually buffered, so you may need to flush it once the command has been received, via cout << flush or cout.flush()

      – Remy Lebeau
      Nov 26 '18 at 1:39


















    2














    You are ignoring the return value of read() to know how many bytes are in the buffer.



    read() returns the actual number of bytes that were read, which may be fewer than you requested. So you need to call read() in a loop until you have read all of the bytes you are expecting, eg:



    int readAll(int sock, void *buffer, size_t buflen)
    {
    unsigned char* pbuf = reinterpret_cast<unsigned char*>(buffer);
    while (buflen > 0) {
    int numRead = read(sock, pbuf, buflen);
    if (numRead < 0) return -1;
    if (numRead == 0) return 0;
    pbuf += numRead;
    buflen -= numRead;
    }
    return 1;
    }


    Also, after reading the buffer, you are treating it as if it were null-terminated, but it is not, which is why you get extra garbage in your output.



    More importantly, mapData != command.c_str() will ALWAYS be true, so your while loop iterates indefinitely (until a socket error occurs), which is not what you want. You want the loop to end when you receive a "command> " string instead.



    mapData is initially NULL, and c_str() NEVER returns NULL, so the loop ALWAYS iterates at least once.



    Then you allocate and free mapData but don't reset it to NULL, so it is left pointing at invalid memory. Which doesn't really matter, since your while loop is just comparing pointers. c_str() will NEVER return a pointer to memory that mapData ever points to.



    To end your loop correctly, you need to compare the contents of mapData after reading, not compare its memory address.



    Try this instead:



    char *mapData = NULL;
    uint64_t dataSize = 0;
    const string command = "command> ";
    bool keepLooping = true;

    do {
    if (readAll(mySocket, &dataSize, sizeof(dataSize)) <= 0) {
    cerr << "**Error: could not read text size" << endl;
    return 1;
    }

    if (dataSize == 0)
    continue;

    mapData = new char[dataSize];

    if (readAll(mySocket, mapData, dataSize) <= 0) {
    cerr << "**Error: could not read text" << endl;
    delete mapData;
    return 1;
    }

    cout.write(mapData, dataSize);

    keepLooping = (dataSize != command.size()) || (strncmp(mapData, command.c_str(), command.size()) != 0);

    delete mapData;
    }
    while (keepLooping);


    Alternatively:



    string mapData;
    uint64_t dataSize = 0;
    const string command = "command> ";

    do {
    if (readAll(mySocket, &dataSize, sizeof(dataSize)) <= 0) {
    cerr << "**Error: could not read text size" << endl;
    return 1;
    }

    mapData.resize(dataSize);

    if (dataSize > 0) {
    if (readAll(mySocket, &mapData[0], dataSize) <= 0) {
    cerr << "**Error: could not read text" << endl;
    return 1;
    }

    cout << mapData;
    }
    }
    while (mapData != command);





    share|improve this answer


























    • Worked perfectly! Only issue is its not printing out the "command> " itself but a little messing around should fix that. Thank you!

      – ejscribner
      Nov 25 '18 at 21:17











    • @ejscribner it should be printing out everything that is received. However, cout is usually buffered, so you may need to flush it once the command has been received, via cout << flush or cout.flush()

      – Remy Lebeau
      Nov 26 '18 at 1:39
















    2












    2








    2







    You are ignoring the return value of read() to know how many bytes are in the buffer.



    read() returns the actual number of bytes that were read, which may be fewer than you requested. So you need to call read() in a loop until you have read all of the bytes you are expecting, eg:



    int readAll(int sock, void *buffer, size_t buflen)
    {
    unsigned char* pbuf = reinterpret_cast<unsigned char*>(buffer);
    while (buflen > 0) {
    int numRead = read(sock, pbuf, buflen);
    if (numRead < 0) return -1;
    if (numRead == 0) return 0;
    pbuf += numRead;
    buflen -= numRead;
    }
    return 1;
    }


    Also, after reading the buffer, you are treating it as if it were null-terminated, but it is not, which is why you get extra garbage in your output.



    More importantly, mapData != command.c_str() will ALWAYS be true, so your while loop iterates indefinitely (until a socket error occurs), which is not what you want. You want the loop to end when you receive a "command> " string instead.



    mapData is initially NULL, and c_str() NEVER returns NULL, so the loop ALWAYS iterates at least once.



    Then you allocate and free mapData but don't reset it to NULL, so it is left pointing at invalid memory. Which doesn't really matter, since your while loop is just comparing pointers. c_str() will NEVER return a pointer to memory that mapData ever points to.



    To end your loop correctly, you need to compare the contents of mapData after reading, not compare its memory address.



    Try this instead:



    char *mapData = NULL;
    uint64_t dataSize = 0;
    const string command = "command> ";
    bool keepLooping = true;

    do {
    if (readAll(mySocket, &dataSize, sizeof(dataSize)) <= 0) {
    cerr << "**Error: could not read text size" << endl;
    return 1;
    }

    if (dataSize == 0)
    continue;

    mapData = new char[dataSize];

    if (readAll(mySocket, mapData, dataSize) <= 0) {
    cerr << "**Error: could not read text" << endl;
    delete mapData;
    return 1;
    }

    cout.write(mapData, dataSize);

    keepLooping = (dataSize != command.size()) || (strncmp(mapData, command.c_str(), command.size()) != 0);

    delete mapData;
    }
    while (keepLooping);


    Alternatively:



    string mapData;
    uint64_t dataSize = 0;
    const string command = "command> ";

    do {
    if (readAll(mySocket, &dataSize, sizeof(dataSize)) <= 0) {
    cerr << "**Error: could not read text size" << endl;
    return 1;
    }

    mapData.resize(dataSize);

    if (dataSize > 0) {
    if (readAll(mySocket, &mapData[0], dataSize) <= 0) {
    cerr << "**Error: could not read text" << endl;
    return 1;
    }

    cout << mapData;
    }
    }
    while (mapData != command);





    share|improve this answer















    You are ignoring the return value of read() to know how many bytes are in the buffer.



    read() returns the actual number of bytes that were read, which may be fewer than you requested. So you need to call read() in a loop until you have read all of the bytes you are expecting, eg:



    int readAll(int sock, void *buffer, size_t buflen)
    {
    unsigned char* pbuf = reinterpret_cast<unsigned char*>(buffer);
    while (buflen > 0) {
    int numRead = read(sock, pbuf, buflen);
    if (numRead < 0) return -1;
    if (numRead == 0) return 0;
    pbuf += numRead;
    buflen -= numRead;
    }
    return 1;
    }


    Also, after reading the buffer, you are treating it as if it were null-terminated, but it is not, which is why you get extra garbage in your output.



    More importantly, mapData != command.c_str() will ALWAYS be true, so your while loop iterates indefinitely (until a socket error occurs), which is not what you want. You want the loop to end when you receive a "command> " string instead.



    mapData is initially NULL, and c_str() NEVER returns NULL, so the loop ALWAYS iterates at least once.



    Then you allocate and free mapData but don't reset it to NULL, so it is left pointing at invalid memory. Which doesn't really matter, since your while loop is just comparing pointers. c_str() will NEVER return a pointer to memory that mapData ever points to.



    To end your loop correctly, you need to compare the contents of mapData after reading, not compare its memory address.



    Try this instead:



    char *mapData = NULL;
    uint64_t dataSize = 0;
    const string command = "command> ";
    bool keepLooping = true;

    do {
    if (readAll(mySocket, &dataSize, sizeof(dataSize)) <= 0) {
    cerr << "**Error: could not read text size" << endl;
    return 1;
    }

    if (dataSize == 0)
    continue;

    mapData = new char[dataSize];

    if (readAll(mySocket, mapData, dataSize) <= 0) {
    cerr << "**Error: could not read text" << endl;
    delete mapData;
    return 1;
    }

    cout.write(mapData, dataSize);

    keepLooping = (dataSize != command.size()) || (strncmp(mapData, command.c_str(), command.size()) != 0);

    delete mapData;
    }
    while (keepLooping);


    Alternatively:



    string mapData;
    uint64_t dataSize = 0;
    const string command = "command> ";

    do {
    if (readAll(mySocket, &dataSize, sizeof(dataSize)) <= 0) {
    cerr << "**Error: could not read text size" << endl;
    return 1;
    }

    mapData.resize(dataSize);

    if (dataSize > 0) {
    if (readAll(mySocket, &mapData[0], dataSize) <= 0) {
    cerr << "**Error: could not read text" << endl;
    return 1;
    }

    cout << mapData;
    }
    }
    while (mapData != command);






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 24 '18 at 17:57

























    answered Nov 24 '18 at 17:36









    Remy LebeauRemy Lebeau

    339k19262456




    339k19262456













    • Worked perfectly! Only issue is its not printing out the "command> " itself but a little messing around should fix that. Thank you!

      – ejscribner
      Nov 25 '18 at 21:17











    • @ejscribner it should be printing out everything that is received. However, cout is usually buffered, so you may need to flush it once the command has been received, via cout << flush or cout.flush()

      – Remy Lebeau
      Nov 26 '18 at 1:39





















    • Worked perfectly! Only issue is its not printing out the "command> " itself but a little messing around should fix that. Thank you!

      – ejscribner
      Nov 25 '18 at 21:17











    • @ejscribner it should be printing out everything that is received. However, cout is usually buffered, so you may need to flush it once the command has been received, via cout << flush or cout.flush()

      – Remy Lebeau
      Nov 26 '18 at 1:39



















    Worked perfectly! Only issue is its not printing out the "command> " itself but a little messing around should fix that. Thank you!

    – ejscribner
    Nov 25 '18 at 21:17





    Worked perfectly! Only issue is its not printing out the "command> " itself but a little messing around should fix that. Thank you!

    – ejscribner
    Nov 25 '18 at 21:17













    @ejscribner it should be printing out everything that is received. However, cout is usually buffered, so you may need to flush it once the command has been received, via cout << flush or cout.flush()

    – Remy Lebeau
    Nov 26 '18 at 1:39







    @ejscribner it should be printing out everything that is received. However, cout is usually buffered, so you may need to flush it once the command has been received, via cout << flush or cout.flush()

    – Remy Lebeau
    Nov 26 '18 at 1:39















    1














    like @eozd pointed out, calling malloc and free in your loop is a bad idea since you use return statements. Your code may leak memory. You should ensure you call free before returns. Even better, you could declare your buffer outside of while loop, and use break instead of return, and call free if there was en error



    Looking at your solution, it seems that the communication protocol involves sending data size first, followed by the actual data. How is data size written to the wire? You may need to convert it from network byte order.



    To debug, you could print out the value of dataSize before every read to make sure that it is what you expect






    share|improve this answer
























    • Before each line of actual data, it sends a size_t that represents how many bytes need to be read, however when I print the dataSize it prints the proper size (18 for line 1, then 10 for the rest of the lines) but still leaves the 'Miffy!' at the end of each of the remaining shorter lines.

      – ejscribner
      Nov 24 '18 at 17:07











    • what happens if you put memset(buffer, 0, datasize); right before free(buffer)?

      – HappyKeyboard
      Nov 24 '18 at 17:35
















    1














    like @eozd pointed out, calling malloc and free in your loop is a bad idea since you use return statements. Your code may leak memory. You should ensure you call free before returns. Even better, you could declare your buffer outside of while loop, and use break instead of return, and call free if there was en error



    Looking at your solution, it seems that the communication protocol involves sending data size first, followed by the actual data. How is data size written to the wire? You may need to convert it from network byte order.



    To debug, you could print out the value of dataSize before every read to make sure that it is what you expect






    share|improve this answer
























    • Before each line of actual data, it sends a size_t that represents how many bytes need to be read, however when I print the dataSize it prints the proper size (18 for line 1, then 10 for the rest of the lines) but still leaves the 'Miffy!' at the end of each of the remaining shorter lines.

      – ejscribner
      Nov 24 '18 at 17:07











    • what happens if you put memset(buffer, 0, datasize); right before free(buffer)?

      – HappyKeyboard
      Nov 24 '18 at 17:35














    1












    1








    1







    like @eozd pointed out, calling malloc and free in your loop is a bad idea since you use return statements. Your code may leak memory. You should ensure you call free before returns. Even better, you could declare your buffer outside of while loop, and use break instead of return, and call free if there was en error



    Looking at your solution, it seems that the communication protocol involves sending data size first, followed by the actual data. How is data size written to the wire? You may need to convert it from network byte order.



    To debug, you could print out the value of dataSize before every read to make sure that it is what you expect






    share|improve this answer













    like @eozd pointed out, calling malloc and free in your loop is a bad idea since you use return statements. Your code may leak memory. You should ensure you call free before returns. Even better, you could declare your buffer outside of while loop, and use break instead of return, and call free if there was en error



    Looking at your solution, it seems that the communication protocol involves sending data size first, followed by the actual data. How is data size written to the wire? You may need to convert it from network byte order.



    To debug, you could print out the value of dataSize before every read to make sure that it is what you expect







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 24 '18 at 17:02









    HappyKeyboardHappyKeyboard

    1066




    1066













    • Before each line of actual data, it sends a size_t that represents how many bytes need to be read, however when I print the dataSize it prints the proper size (18 for line 1, then 10 for the rest of the lines) but still leaves the 'Miffy!' at the end of each of the remaining shorter lines.

      – ejscribner
      Nov 24 '18 at 17:07











    • what happens if you put memset(buffer, 0, datasize); right before free(buffer)?

      – HappyKeyboard
      Nov 24 '18 at 17:35



















    • Before each line of actual data, it sends a size_t that represents how many bytes need to be read, however when I print the dataSize it prints the proper size (18 for line 1, then 10 for the rest of the lines) but still leaves the 'Miffy!' at the end of each of the remaining shorter lines.

      – ejscribner
      Nov 24 '18 at 17:07











    • what happens if you put memset(buffer, 0, datasize); right before free(buffer)?

      – HappyKeyboard
      Nov 24 '18 at 17:35

















    Before each line of actual data, it sends a size_t that represents how many bytes need to be read, however when I print the dataSize it prints the proper size (18 for line 1, then 10 for the rest of the lines) but still leaves the 'Miffy!' at the end of each of the remaining shorter lines.

    – ejscribner
    Nov 24 '18 at 17:07





    Before each line of actual data, it sends a size_t that represents how many bytes need to be read, however when I print the dataSize it prints the proper size (18 for line 1, then 10 for the rest of the lines) but still leaves the 'Miffy!' at the end of each of the remaining shorter lines.

    – ejscribner
    Nov 24 '18 at 17:07













    what happens if you put memset(buffer, 0, datasize); right before free(buffer)?

    – HappyKeyboard
    Nov 24 '18 at 17:35





    what happens if you put memset(buffer, 0, datasize); right before free(buffer)?

    – HappyKeyboard
    Nov 24 '18 at 17:35











    0














    You should clear the buffer too. Add:



     memset(mapData, 0, dataSize);


    after the malloc.






    share|improve this answer




























      0














      You should clear the buffer too. Add:



       memset(mapData, 0, dataSize);


      after the malloc.






      share|improve this answer


























        0












        0








        0







        You should clear the buffer too. Add:



         memset(mapData, 0, dataSize);


        after the malloc.






        share|improve this answer













        You should clear the buffer too. Add:



         memset(mapData, 0, dataSize);


        after the malloc.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 24 '18 at 14:55









        BuddyBuddy

        8,68753051




        8,68753051






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53459312%2fclearing-buffer-while-reading-in-binary-data-from-a-server-in-c%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Wiesbaden

            Marschland

            Dieringhausen