Clearing buffer while reading in binary data from a server in C++
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.
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
add a comment |
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.
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
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 thebuffer
variable. Pass&dataSize
directly to theread
call. Also passsizeof dataSize
instead of hard-coding8
. And don't forget thatread
will return0
if the socket is close, something you need to handle as well. Lastly, if you use TCP sockets, then a singleread
call may return less than what was written, you need to callread
in a loop until all requested data has been received.
– Some programmer dude
Nov 24 '18 at 14:53
2
Use the return value fromread
which is the number of bytes.
– stark
Nov 24 '18 at 16:34
add a comment |
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.
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
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.
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
c++ server binary-data datareader
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 thebuffer
variable. Pass&dataSize
directly to theread
call. Also passsizeof dataSize
instead of hard-coding8
. And don't forget thatread
will return0
if the socket is close, something you need to handle as well. Lastly, if you use TCP sockets, then a singleread
call may return less than what was written, you need to callread
in a loop until all requested data has been received.
– Some programmer dude
Nov 24 '18 at 14:53
2
Use the return value fromread
which is the number of bytes.
– stark
Nov 24 '18 at 16:34
add a comment |
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 thebuffer
variable. Pass&dataSize
directly to theread
call. Also passsizeof dataSize
instead of hard-coding8
. And don't forget thatread
will return0
if the socket is close, something you need to handle as well. Lastly, if you use TCP sockets, then a singleread
call may return less than what was written, you need to callread
in a loop until all requested data has been received.
– Some programmer dude
Nov 24 '18 at 14:53
2
Use the return value fromread
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
add a comment |
3 Answers
3
active
oldest
votes
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);
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, viacout << flush
orcout.flush()
– Remy Lebeau
Nov 26 '18 at 1:39
add a comment |
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
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 putmemset(buffer, 0, datasize);
right beforefree(buffer)
?
– HappyKeyboard
Nov 24 '18 at 17:35
add a comment |
You should clear the buffer too. Add:
memset(mapData, 0, dataSize);
after the malloc
.
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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);
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, viacout << flush
orcout.flush()
– Remy Lebeau
Nov 26 '18 at 1:39
add a comment |
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);
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, viacout << flush
orcout.flush()
– Remy Lebeau
Nov 26 '18 at 1:39
add a comment |
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);
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);
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, viacout << flush
orcout.flush()
– Remy Lebeau
Nov 26 '18 at 1:39
add a comment |
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, viacout << flush
orcout.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
add a comment |
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
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 putmemset(buffer, 0, datasize);
right beforefree(buffer)
?
– HappyKeyboard
Nov 24 '18 at 17:35
add a comment |
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
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 putmemset(buffer, 0, datasize);
right beforefree(buffer)
?
– HappyKeyboard
Nov 24 '18 at 17:35
add a comment |
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
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
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 putmemset(buffer, 0, datasize);
right beforefree(buffer)
?
– HappyKeyboard
Nov 24 '18 at 17:35
add a comment |
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 putmemset(buffer, 0, datasize);
right beforefree(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
add a comment |
You should clear the buffer too. Add:
memset(mapData, 0, dataSize);
after the malloc
.
add a comment |
You should clear the buffer too. Add:
memset(mapData, 0, dataSize);
after the malloc
.
add a comment |
You should clear the buffer too. Add:
memset(mapData, 0, dataSize);
after the malloc
.
You should clear the buffer too. Add:
memset(mapData, 0, dataSize);
after the malloc
.
answered Nov 24 '18 at 14:55
BuddyBuddy
8,68753051
8,68753051
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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 theread
call. Also passsizeof dataSize
instead of hard-coding8
. And don't forget thatread
will return0
if the socket is close, something you need to handle as well. Lastly, if you use TCP sockets, then a singleread
call may return less than what was written, you need to callread
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