Find the answer to your Linux question:
Results 1 to 4 of 4
I have a small program which consists of a server and a client. The server sends a file to the client through UDP socket line by line. Currently i use ...
  1. #1
    Just Joined!
    Join Date
    May 2008
    Location
    India
    Posts
    15

    Question How to optimise file transfer through UDP sockets?

    I have a small program which consists of a server and a client. The server sends a file to the client through UDP socket line by line. Currently i use fgets() function to read a line into a buffer from the file at the server end and then use sendto() function to transfer the data through socket to the client.

    Now, i want to know if the method i am using for transferring the file contents is correct i.e line by line or can i use a different method to transfer the file since UDP sockets can transfer huge chunks of data at once. This means that instead of reading and transferring one line at a time using fgets() function, should i use fread() function to read and transfer a large chunk of data instead of transferring a single line at a time? Will that be better than the current method? Basically i want the best optimal code, since my server shouldn't take much memory.

    Here's a sample code:

    Server:
    FILE *rec_file;
    char line[LINE_MAX];
    char *buf;

    /* Open the file to be sent to the client */
    if ((rec_file = fopen("myfile", "r")) == NULL) {
    perror("fopen");
    return NULL;
    }

    /* Send the file contents to the client line by line */
    while (fgets (line, LINE_MAX, rec_file)) {
    buf = (char *) malloc (strlen (line) + 1);
    strcpy(buf, line);

    if ((numbytes = sendto (sockfd, buf, strlen (buf), 0, (struct sockaddr *) &client_addr, sizeof (client_addr))) == -1) {

    perror ("sendto");
    free (buf);
    return NULL;
    }
    free (buf);

    }
    fclose (rec_file);
    Client:
    char buf[100];

    /* Read the file contents from the socket and write it to a text file */
    while ((retval = poll (ufds, 1, TIMEOUT)) > 0) {
    if ((numbytes = recvfrom (sockfd, buf, sizeof (buf) , 0,
    (struct sockaddr *) &recv_addr, &addr_len)) > 0) {
    buf[numbytes] = '\0';
    if ((numbytes = fwrite(&buf, strlen (buf), 1, fpRec)) <= 0) {
    perror("fwrite");
    close (sockfd);
    return -1;
    }
    fflush(fpRec);
    } else {
    perror("recvfrom");
    close (sockfd);
    return -1;
    }
    }

  2. #2
    Linux Engineer wje_lf's Avatar
    Join Date
    Sep 2007
    Location
    Mariposa
    Posts
    1,192
    Basically i want the best optimal code, since my server shouldn't take much memory.
    So you're optimizing for code size rather than execution time?

    In that case, fread() is the way to go.

    But you're aware that UDP doesn't do much error recovery for you, right? For your code to be robust, you'll need to do error detection and recovery yourself.

    If you want a robust implementation and you want small code, use TCP instead. You'll still have to check for error status, as you do now, but you get a whole layer of error recovery code built right into the TCP stack.

    Hope this helps.
    --
    Bill

    Old age and treachery will overcome youth and skill.

  3. #3
    Just Joined!
    Join Date
    May 2008
    Location
    India
    Posts
    15
    Thanks for the reply!
    Actually i am working on a client project and they use UDP so i have to stick to UDP.

    BTW, i am now using read() API to read a pre-defined chunk of data instead of using the fgets() API. I am taking the UDP MTU size as 512 bytes.

    I am using some error checking by sending an acknowledgement back to the sender that the packet has been received.
    Is this ok or should i use the checksum method? More details on usage of checksum would be of great help.

  4. #4
    Linux Engineer wje_lf's Avatar
    Join Date
    Sep 2007
    Location
    Mariposa
    Posts
    1,192
    i am now using read()
    Good. There's nothing wrong with using that instead of fread().
    I am using some error checking by sending an acknowledgement back to the sender that the packet has been received.
    Is this ok or should i use the checksum method?
    I'd do this:
    1. Put a packet number in each packet.
    2. Add a checksum to each packet.
    3. Send an acknowledgement, and let it contain the packet number of the packet which has just been received.

    More details on usage of checksum would be of great help.
    A good intro is here.
    --
    Bill

    Old age and treachery will overcome youth and skill.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...