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:
and 1 on server:
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:
fopen
creates file on disk (by usingopen(2)
[orcreat(2)
] system call) , allocates internal bufferfwrite
repeatedly fills internal buffer. each time buffer fills boundary (determinedbufsiz
-- seesetbuf(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
Post a Comment