When transferring a file, bytes are lost. Help understand what the problem is, please

Hello. I’m trying to transfer a file over the network, but for some reason not all bytes reach the client.
The write function sends the number of bytes needed, but the accept function takes fewer bytes than necessary. What could be the problem?
send file

    gchar *contents = NULL;
    gsize bytes = 0;

    g_file_load_contents(file, NULL, &contents, &bytes, NULL, NULL);
    g_output_stream_write_all(out, contents, size, NULL, NULL, NULL);

recv file

        while ((read = g_input_stream_read(in, buf, sizeof(buf), NULL,  //sizeof(buf) == 65536
                                           NULL)) > 0) {
            bytes += read;
            if (bytes > size)
                break;
            if (g_output_stream_write(G_OUTPUT_STREAM(out), buf, read, NULL, // writing to file
                                      NULL) < 0) {
                break;
            }
        }

here is full server-side file https://github.com/unitucode/uchat/blob/server/server/src/client_handler/api/up_down_load_file/download_file.c
and full client-side file
https://github.com/unitucode/uchat/blob/server/client/src/api/up_down_load_file/file_read.c

            bytes += read;
            if (bytes > size)
                break;

You probably want to do that after g_output_stream_write

No, size == size of file. So if received bytes bigger than size, I must break the cycle. Or I’m wrong?

In addition, I noticed that the client does not read the first 3900-4000 bytes.

Well yes, but you still want to write the final chunk

It helpful though to have

Otherwise it’s hard to give useful answers (since we don’t really know what the problem is :slight_smile: )

    g_file_load_contents(file, NULL, &contents, &bytes, NULL, NULL);
    g_output_stream_write_all(out, contents, size, NULL, NULL, NULL);

I notice here your mixing “bytes” and “size”, but that probably isn’t the cause of your problems

I don’t see you checking GErrors anywhere - again probably not the problem here but could be useful

You could probably use g_file_read/g_output_stream_splice actually

That said skimming your code I’m not immediately seeing a smoking gun

1 Like
g_print("splice = %ld\n", g_output_stream_splice(G_OUTPUT_STREAM(out), in, G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, NULL, NULL));

On server side it returns 461348, and on client side 457355

Maybe this has something to do with g_data_input_stream_read_line_finish. Before these, I use this connection with GDataInputStream

If I don’t use

gchar *msg = g_data_input_stream_read_line_finish(
         G_DATA_INPUT_STREAM(source_object), res, NULL, NULL);

It works good, but why?

How the file transfer occurs.

  1. Sending size to client via GDataOutputStream
    // sleep(2);
  2. Sending a file byte by byte
    If you put sleep between these actions, it will work well. But why??? :thinking:

How the file reception should occur:

  1. Get the size and the name.
  2. Open the file.
  3. Tell the sender whether or not the file could be opened.
  4. Hear the file’s content.
  5. Write that content.
  6. Close the file.

You don’t do step 3. Your sender didn’t give the receiver enough time to do step 2. Probably, by the time step 2 had finished, almost 4000 bytes already had been sent and lost.

2 Likes

Thanks for the correct answer. Thank you all for your help! :slightly_smiling_face:

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.