How to transfer file via socket?

I tried many options with transferring files through a socket with different streams. But for some reason, bytes sometimes do not reach. Please can give an example of how to transfer files through a socket safely?

1 Like

Hii
You say you have tried, can you share the code so we can tell you what is wrong? You can also refer to the various socket related test files at GIO’s repo. For example socket-client.c.
:smiley:

Hello, I have already solved the problem. I didn’t work with threads correctly, so not all packages were processed correctly

1 Like

Can you share the code you used (simplifying it as required), so future visitors can also learn ? :smile:

CLIENT

GFile *file = g_file_new_for_path(path);
GFileInfo *info = g_file_query_info(file, "standard::size,standard::name", G_FILE_QUERY_INFO_NONE, NULL, NULL);
GOutputStream *out = g_io_stream_get_output_stream(G_IO_STREAM(conn)); //get io from socket
g_file_load_contents_async(file, NULL, file_ready, conn);

static void file_ready(GObject *source_object, GAsyncResult *res, gpointer user_data) {
    char *contents = NULL;
    gsize length = 0;
    GOutputStream *out = g_io_stream_get_output_stream(G_IO_STREAM(user_data));
    g_file_load_contents_finish(G_FILE(source_object), res, &contents, &length, NULL, NULL);
    g_print("send = %ld\n", g_output_stream_write(out, contents, length, NULL, NULL));
    g_io_stream_close(G_IO_STREAM(user_data), NULL, NULL);
    (void)res;
}

Before transferring the file, I send its size so that the server can get ready

SERVER

GFile *file = g_file_new_for_path(name);
char buf[size + 1];
bzero(buf, sizeof(buf));
g_print("read = %ld\n", g_input_stream_read(client->in_s, buf, size, NULL, NULL)); //read from client input stream to but
g_file_replace_contents(file, buf, size, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL, NULL);
1 Like

I would read the file in chunks rather than all at once, avoids loading the whole file into memory and lets you start transferring data faster

char buf[size + 1];

That’s a VLA, which is almost certainly not what you want - when this is data coming over a network it’s highly likely you will overflow that stack at some point

You should instead read from the socket in chunks into a fixed-sized buffer until you reach the end

2 Likes

Hi, I am fetching a file, but not all bytes reach the server. Tell me, please, how to fix this?
g_output_stream_write(out, contents, length, NULL, NULL);
And reading
while ((read = g_input_stream_read(client->in_s, buf, 1024, NULL, NULL)) > 0)

Fixed with g_output_stream_write_all