1

i have created server and client to communication. Client sends binary data of image then server receives it and writes to file. I have pasted necessary code below.

            std::stringstream binStr;

            bytes_received = recv(new_sd, &binStr, sizeof(binStr) ,0);
            std::cout << binStr << std::endl;

            char buff[1024*1024];
            std::string image;

            while (!binStr.eof())
            {
                binStr.read(buff, sizeof (buff));
                image.append(buff, binStr.gcount());
            }

            int id = 1;
            std::stringstream ss2;
            ss2 << id;
            std::string str2 = ss2.str();
            std::ofstream img(str2.c_str(),std::ios::binary);
            std::cout << image.c_str() << std::endl;
            img.write(image.c_str(), image.length());

this code creates file with name as id , but its an empty file. How can i fix it?

Ulfsark
  • 902
  • 1
  • 11
  • 26

1 Answers1

1

You cannot recv() into a std::stringstream like you are attempting to. You have to recv() into a buffer first and then you can copy that data into your std::stringstream afterwards. However, you are using the std::stringstream only as an intermediate to get data into your buff buffer, and then from there to a std::string. You can get rid of the std::stringstream altogether and recv() directly into buff instead. I would even go as far as getting rid of the std::string altogether as well, as you do not really need it:

int id = 1;
std::stringstream ss2;
ss2 << id;
std::ofstream img(ss2.str().c_str(), std::ios::binary);

// 1MB is a lot to put on the stack, use the heap instead
std::vector<char> buff(1024*1024);
do
{
    bytes_received = recv(new_sd, &buff[0], buff.size(), 0);
    if (bytes_received < 0)
        break; // ERROR!

    if (bytes_received == 0)
        break; // DISCONNECT!

    for (int i = 0; i < bytes_received; ++i)
        std::cout << buff[i];
    std::cout << std::endl;

    img.write(&buff[0], bytes_received);

    // TODO: if reached the end of the image, stop here
}
while (true);

Unless the sender closes its end of the connection after sending the image data to you, then you need a way to know when the end of the image has been reached. The sender will have to send the image data length to you so you know when to stop reading.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thank you for your help, but i don't know how to implement your TODO. I have sent "size_t imageSize" from client. – Ulfsark Jan 27 '14 at 10:09
  • I changed write part and problem solved. `img.write(&buff[8], bytes_received);` Opened image file with notepad and saw 8 x "/00" characters. Don't know how did that chars put there. – Ulfsark Jan 27 '14 at 14:38
  • Why did you make that change? That will break the code. It needs to be `&buff[0]`. As for the TODO, are you creating the sender that is sending the image data? If so, then you need to update it to send the image data length before sending the image data. Otherwise, you need to determine how the sender is doing that. If no length is being sent, the only way to detect the end of the data is by the connection being closed. – Remy Lebeau Jan 27 '14 at 16:10
  • I have changed buff[0] because the images in sender(client) and receiver(server) are different. If i open images with vim(or notepad) , received image has extra 8 `/00` characters. Then i started from buff[8] To ignore these characters. – Ulfsark Jan 28 '14 at 07:54
  • Those first 8 bytes are likely important or else the sender would not be sending them in the first place. If you must start at the 8th byte then you must subtract 8 from `bytes_received` or else you will read 8 bytes past the edge of `buff` when you `write()` it, thus writing random data to your file (if not causing an access violation error). – Remy Lebeau Jan 28 '14 at 08:09
  • I am not using bytes_received inside of write method. I sent imageSize before send image. Thanks for your help. – Ulfsark Jan 28 '14 at 10:06