Cristian
Cristian

Reputation: 23

Send std::stringstream in named pipe

I have a variable of type std::stringstream where I write data in blob format, after which I want to send it to the pipe, from here the data is taken over by another application and sent via tcp socket. When I call std::stringstream.str() it shows me the correct information. If I give std::cout << std::stringstream.str().c_str() shows me empty result. I tried to send std::stringstream.str().c_str() to the pipe and get an empty space in the other application.

std::stringstream stream;
int fd;
const char* fifo = "/tmp/adpluspipe";

/* create the FIFO (named pipe) */
mkfifo(fifo, 0666);

/* write data to the FIFO */
fd = open(fifo, O_WRONLY);
write(fd, stream.str().data(), 84);
close(fd);

/* remove the FIFO */
unlink(fifo);

The content of the stream variable is the one in the image: content of the stream variable

I receive a string of bytes through the socket, I decode that content according to the encryption documentation, I apply some filters and then I encode it only with the data I need. It has many areas with '\0' because in the end it must have the same length, so that when applying the decoding documentation it can work. The code is quite large and complex, so I couldn't display it. That encoded content looks like the one in the picture and I have to send it through a pipe to another application. I used std::stringstream, because here I was able to add byte by byte according to the encryption documentation. The write code in that variable is:

// The data is added like this:
int value = std::bitset<8>("00111101").to_ulong();
// or
int value = 80;
// and so on



void writeBytes(std::stringstream &stream, int value, int valueSize)
{
    unsigned char bytes[valueSize];

    if(valueSize == 1){
        bytes[0] = value & 0xFF;
    }

    if(valueSize == 2){
        bytes[0] = (value >> 8) & 0xFF;
        bytes[1] = value & 0xFF;
    }

    if(valueSize == 4){
        bytes[0] = (value >> 24) & 0xFF;
        bytes[1] = (value >> 16) & 0xFF;
        bytes[2] = (value >> 8) & 0xFF;
        bytes[3] = value & 0xFF;
    }

    stream.write(reinterpret_cast<char*>(&bytes), sizeof(bytes));

    memset(bytes, 0, sizeof(bytes));

}

Upvotes: 0

Views: 719

Answers (1)

lvella
lvella

Reputation: 13453

When you do:

std::cout << std::stringstream.str().c_str();

it tries to interpret the data as a C string, and from the image, I can see that it clearly is not a C string, because it has null character '\0' in many places. Every C++ function that handles a C string will expect the string to be terminated by '\0', so it stops processing the as soon as it sees the null character. That is not a problem when you use std::string (as returned by .str()) because it stores the size of the string, and does not rely on null character for a terminator. For a std::string, '\0' is not special.

As for why you can't see the contents on the receiving side, I can only speculate, since you haven't provided the code, but I would assume you are handling the data as a C string (const char *), no?

Upvotes: 2

Related Questions