David
David

Reputation: 537

Multiple writes in server socket to single read in client socket program?

I've seen a lot of questions related to what I'm trying to do but I haven't been able to get any solution to work for me as yet.

I'm try to write two socket programs (one client and one server) so that the server is able to send files of any type (by bytes) to the client. I'm not sure how to construct/coordinate the following:

  1. (in the server) the read statement(s) to get data from the file (I'm using fread())

  2. (in the server) the write statement(s) to send the data to the client (I'm using write())

  3. (in the client) the read statement(s) to receive data from the server (I'm using read())

  4. (in the client) the write statement(s) to write the data received from the server to a file (I'm using fwrite())

I want to transmit the data in chunks of bytes. Will one fread() statement and one write() statement in the server be sufficient regardless of how large the file is? (or does that depend on the size of my buffer?) On the client side, will one call to read() and one call to fwrite() be enough? (or does that depend on the size of my buffer?)

I'm new to Socket Programming. Thanks in advance! Parts of my server and client below:

Client Side:

/*try to get file from server*/

  char receive_buffer[256];
    FILE * new_file;

    int bytes_received = 0;

    new_file = fopen("newfile.txt", "w");

    bytes_received = read(conn_s, receive_buffer, 256);

    printf("Received %d bytes\n", bytes_received);

    while( bytes_received > 0)
    {   
        bytes_received = read(conn_s, receive_buffer, 256);
        printf("Received %d bytes\n", bytes_received);
        fwrite(receive_buffer, 1, bytes_received, new_file);
        printf("writing bytes!\n");
        break;
    }
    if(bytes_received < 0)
    {
        printf("/nError reading bytes of data/n");
    }

Parts of the server code:

FILE * file_to_get = fopen("sample.txt", "rb");
    if(file_to_get == NULL)
    {
        printf("No such file!");
        exit(0);
    }
    while(1)
    {
        unsigned char buff[256];
        int num_read = fread(buff, 1, 256, file_to_get);
        printf("read %d bytes\n", num_read);
        if(num_read > 0)
        {
            write(conn_s, buff, num_read);
            printf("writing %d bytes\n", num_read);
        }    

        if(num_read < 256)
        {
            if(feof(file_to_get))
                printf("End of file\n");
            if(ferror(file_to_get))
                printf("Error reading bytes\n");
            break;
        }    
    }

Upvotes: 0

Views: 3172

Answers (1)

Barmar
Barmar

Reputation: 780723

When sending to the network, you can use a single call to write(). If there's not enough buffer space in the kernel for the whole thing, write() will block until it's able to process all of it. You can also write it in chunks, that's fine as well. It doesn't really matter.

When reading from the network, you have to call read() in a loop. The buffer size you specify when calling read() is just the maximum it's allowed to return, it won't wait for that much to be received. So it can (and often does) return less than this. Just keep calling read() until it returns 0 to indicate EOF, writing each buffer to the file.

Upvotes: 3

Related Questions