c# - Sending image over socket and saving it on the server -


i'm facing problems project , hope able identify problem i'm not capable see myself.

i'm trying send picture c# client (windows) c server running on linux system. i'm transmitting image binary data via tcp socket , works fine, problem when i'm writing received buffer on linux system fwrite, seems information present in buffer, not written or written corrupted value file.

e.g. i'm trying send picture here:

enter image description here

and 1 on server:

enter image description here

the client:

    public static void sendpicture(image image)     {         byte[] imagebytes;          using (memorystream s = new memorystream())         {             image.save(s, imageformat.jpeg);             imagebytes = s.toarray();              s.close();         }          if (imagebytes.length <= 5242880)         {             try             {                 networkstream stream = client.getstream();                  file.writeallbytes("before.jpg", imagebytes);                  //send image size                 byte[] imgsize = bitconverter.getbytes((uint32)imagebytes.length);                  stream.write(imgsize, 0, imgsize.length);                  //get answer server if filesize ok                 byte[] data = new byte[1];                 // recv looks if have partial read,                 // works stream.read(data, 0, data.length)                 int32 count = recv(stream, data, data.length);                  if (count != 1 || data[0] != 0x4)                     return;                  stream.write(imagebytes, 0, imagebytes.length);                  ...             } 

the server:

... // info_buffer_size (1) buffer = malloc (info_buffer_size);   // allow parital reads    if (read_from_client (connfd, buffer, info_buffer_size) == null) {   error_out (buffer,          "error during receiv of client data @ read_from_client");   close (connfd);   continue; }  // reconstruct image_size   uint32_t image_size = buffer[3] << (0x8 * 3) | buffer[2] << (0x8 *                        2) | buffer[1] << 0x8 |                               buffer[0];  fprintf(stderr, "img size: %u\n", image_size);   // check if file size ok    if (check_control (image_size, 1, response) > 0) {   inform_and_close (connfd, response);   continue; }    // inform size ok , we're ready receive image   (void) send (connfd, response, cont_buffer_size, 0);     free (buffer);   buffer = malloc (image_size);     if (read_from_client (connfd, buffer, image_size) == null) {   error_out (buffer,          "error during receiv of client data @ read_from_client");   close (connfd);   continue; }     file *f;    // generate guid name   uuid_t guid;   uuid_generate_random (guid);    char filename[37];   uuid_unparse (guid, filename);    if ((f = fopen (filename, "wb")) == null) {   inform_and_close (connfd, 0x0);   error_out (buffer,          "error while trying open file save data");   continue; }    if (fwrite (buffer, sizeof (buffer[0]), image_size, f) != image_size) {   inform_and_close (connfd, 0x0);   error_out (buffer, "error while writing file");   continue; }    char output[100];   (void) snprintf (output, sizeof (output), "mv %s uploads/%s.jpg",            filename, filename);   system (output);    free (buffer);   close (connfd);    ... 

if receive image , send directly client , client writes received buffer file, fine, there not difference between file has been sent , 1 received. because of i’m quite sure transmission works expected.

if need more, let me know!

fopen creates buffered i/o stream. aren't flushing buffer , closing file. cutting out error checking, you're doing:

f = fopen(filename, "wb"); fwrite(buffer, sizeof (buffer[0]), image_size, f); 

you should add these @ end:

fflush(f); fclose(f); 

fclose flush it's best flush separately can check errors prior closing.

what's happening here (somewhat oversimplified) is:

  1. fopen creates file on disk (by using open(2) [or creat(2)] system call) , allocates internal buffer
  2. fwrite repeatedly fills internal buffer. each time buffer fills boundary (determined bufsiz -- see setbuf(3) man page), fwrite flushes disk (i.e. write(2) system call).

however, when you're finished, end of file still sitting in internal buffer -- because library can't know you're done writing file , didn't happen on bufsiz boundary. either fflush or fclose tell library flush out last partial buffer, writing disk.. fclose underlying os file descriptor closed (which should anyway, or server have "file descriptor leak").


Comments

Popular posts from this blog

account - Script error login visual studio DefaultLogin_PCore.js -

xcode - CocoaPod Storyboard error: -