tags:

views:

160

answers:

5

The problem I am having is printf doesnt print all the data that is being returned from a client response. (verified data is being sent back via packet sniffer)

#define MAXBUFFER    24576
char buffer[MAXBUFFER];
......
datastream = read(sock,buffer,MAXBUFFER - 1);
printf("%s",buffer);
......

What is the best approach to printing all the client data to the console ... while eliminating the potential of a BOF?

+2  A: 

1) You may need to flush stdout to get the data to display: fflush(stdout);

2) If there's a lot of data, then you probably need to use a loop to read from the socket. (If you go this route, you can probably decrease the value of MAXBUFFER, not that you necessarily have to.)

Note: Production code must also recognize when the end of a discrete message has been received -- whether by using a length count, or looking for a specific termination code, or some other means. That's not shown here. (If you use a length count, it's easy enough to sum up the values of "bytesRead" to keep track.)

// Add a byte at the end to allow for a terminating null char
char buffer[MAXBUFFER + 1];
buffer[MAXBUFFER] = '\0';
    //... 
    int bytesRead;
    while((bytesRead = read(sock, buffer, MAXBUFFER)>0)) {
        printf("%s", buffer);
Dan Breslau
+10  A: 

Possible causes:

  1. read is not guaranteed to read all the data at once it just attempts to do so, that's why it returns the number of chars read;

  2. printf with %s will print until the first '\0' [ASCII code 0] in your buffer.

Eugen Constantin Dinca
Thats the problem the output from the client contains a 0 how to I work around this?
ekronnenburg
Additionally, if your buffer does NOT contain any 0s, you'll CRASH
Will
@ekronnenburg: It sounds like the data is in binary format (the bytes may include a mixture of printable and unprintable characters.) If that's the case, you need to convert them to a printable format before you can successfully print them to stdout.
Dan Breslau
The data is actually remote commands that is "ps aux" is sent from the (server) cmd -> (client) exec "ps aux" and returns the output back to the server (reverse connect). So null "0" kills the stream on the server console.
ekronnenburg
@ekronnenburg Not really sure how the output of `ps aux` can have `0` in the middle of it...
Eugen Constantin Dinca
@Will: Actually, it's possible for you not to crash. You will invoke undefined behavior, which means it's perfectly legal for the compiler to format your hard drive.
Billy ONeal
@ekronnenburg you are not clear. You say that you are sending a command like "ps aux" which i believe should not require this huge buffer.
Kedar
Example of a ps aux output from remote machineroot 4682 0.0 0.0 0 0 ? S< Jul23 0:00 [kmpathd/3]root 4683 0.0 0.0 0 <-(dies here)Once I hit the enter key the rest follows 0 ? S< Jul23 0:00 [kmpath_handlerd]root 4711 0.0 0.0 0 0 ? S< Jul23 0:19 [kjournald]root 4713 0.0 0.0 0 0 ? S< Jul23 0:00 [kjournald]
ekronnenburg
Eugen Constantin Dinca
+11  A: 

If the buffer has any zero bytes, they will be treated as string terminators. Is this an ASCII or binary protocol? If the latter, you might want to convert to hex before printing.

Jim Lewis
+1. This was the first thing I thought of. Should probably clarify the meaning "zero bytes" though.
T.E.D.
ASCII .... the printf buffer is being killed by 0 any approaches to this?
ekronnenburg
@ekronnenburg: Yes. As Jim said, encode to hex first. +1.
Billy ONeal
+2  A: 
int numberofbytesread = read(sock,buffer,MAXBUFFER - 1);
write(1, buffer, numberofbytesread);

You should use write(2) instead of printf, as you state you wish to send the data 'raw'. That's my understanding of your response to Dan.

Aaron McDaid
I used write and its exhibiting the same behaviour as printf
ekronnenburg
OK then. I must admit I'm no longer sure what the problem is. Can you be more specific. How many characters are being read? i.e. What is the return value from read()? And how many characters are printed by printf() or write()? Both those functions return the number of characters written.
Aaron McDaid
A: 

Use this example to understand you requirement. Ans: Use write() if you have data with 0 or '\0'

#include<iostream>

using namespace std;

int main()
{
    int ret=0,i;
    char buf[25470];

    for(i=0;i<25470; i++)
    {
        buf[i] = 'a';
    }

    buf[2500] = 0;

    ret = printf("%s ", buf);
    printf("\n \n Printed using 'printf' = %d \n \n", ret);

    ret = write(1,buf,sizeof(buf));
    printf("\n \n Printed using 'write' = %d \n \n", ret);

    return 0;
}

And you really need this big buffer to send a command like "ps aux" ?

Kedar
Using write(1, buffer, sizeof(buffer));It still breaks using writeExample of a "ps aux" output from remote machine root 4682 0.0 0.0 0 0 ? S< Jul23 0:00 [kmpathd/3] root 4683 0.0 0.0 0 <-(stream dies here)Once I hit the enter key the rest follows 0 ? S< Jul23 0:00 [kmpath_handlerd] root 4711 0.0 0.0 0 0 ? S< Jul23 0:19 [kjournald] root 4713 0.0 0.0 0 0 ? S< Jul23 0:00 [kjournald]
ekronnenburg