Question

In: Computer Science

Implement RPC mechanism for a file transfer across a network in ‘C’. **********run the program and...

Implement RPC mechanism for a file transfer across a network in ‘C’.

**********run the program and screenshot************

Solutions

Expert Solution

This is the answer:

.X Code :

const MAXLEN = 1024;

/*
 * Type for storing path
 */
typedef string filename<MAXLEN>;

/*
 * Structure for sending requests. Expects the path of the file
 * and the byte number at which to start reading the file from
 */
struct request {
    filename name;
    int start;
};

/*
 * Type that represents the structure for request
 */
typedef struct request;

/*
 * Type for storing a chunk of the file that is being
 * sent from the server to the client in the current
 * remote procedure call
 */
typedef opaque filechunk[MAXLEN];

/*
 * Response sent by the server to the client as a response
 * to a remote procedure call, containing the file chunk for
 * the current call and number of bytes actually read
 */
struct chunkreceive {
    filechunk data;
    int bytes;
};

/*
 * Type that represents the structure for file's chunks
 * to be received from the server
 */
typedef struct chunkreceive chunkreceive;

/*
 * File data sent by the server from client to store
 * it on the server along with the filename and the
 * number of bytes in the data
 */
struct chunksend {
    filename name;
    filechunk data;
    int bytes;
};

/*
 * Type that represents the structure for file's chunks
 * to be sent to the server 
 */
typedef struct chunk send chunk send;

/*
 * union for returning from remote procedure call returns
 * the proper chunk data response if everything worked fine
 * or will return the error number if an error occurred
 */
union readfile_res switch (int errno) {
    case 0:
        chunkreceive chunk;
    default:
        void;
};

/*
 * Remote procedure defined in the Interface Definition Language
 * of SUN RPC contains PROGRAM and VERSION name definitions and
 * the remote procedure signature
 */
program FTPPROG {
    version FTPVER {
        readfile_res retrieve_file(request *) = 1;
        int send_file(chunksend *) = 2;
    } = 1;
} = 0x20000011;

My Server Code is:

#include <rpc/rpc.h>
#include <stdio.h>
#include "file.h"

extern __thread int errno;

readfile_res* retrieve_file_1_svc(request *req, struct svc_req *rqstp)
{
    FILE *file;
    char data[1024];
    int bytes;
    static readfile_res res;

    file = fopen(req->name, "rb");
    if (file == NULL) {
        res.errno = errno;
        return (&res);
    }

    fseek (file, req->start, SEEK_SET);
    bytes = fread(res.readfile_res_u.chunk.data, 1, 1024, file);

    //res.readfile_res_u.chunk.data = data;
    res.readfile_res_u.chunk.bytes = bytes;

    /*
     * Return the result.
     */
    res.errno = 0;
    fclose(file);
    return (&res);
}
int* send_file_1_svc(chunksend *rec, struct svc_req *rqstp)
{
    FILE *file;
    int write_bytes;
    static int result;

    file = fopen(rec->name, "a");
    if (file == NULL) {
        result = errno;
        return &result;
    }

    write_bytes = fwrite(rec->data, 1, rec->bytes, file);
    fclose(file);

    result = 0;
    return &result;
}

My Client Code should is :

#include <rpc/rpc.h>
#include <stdio.h>
#include <string.h>
#include "file.h"

extern __thread int errno;

int get_file(char *host, char *name)
{
    CLIENT *clnt;
    int total_bytes = 0, write_bytes;
    readfile_res *result;
    request req;
    FILE *file;

    req.name = name;
    req.start = 0;

    /*
     * Create client handle used for calling FTPPROG on
     * the server designated on the command line. Use
     * the TCP protocol when contacting the server.
     */
    clnt = clnt_create(host, FTPPROG, FTPVER, "tcp");
    if (clnt == NULL) {
        /*
         * Couldn't establish a connection with the server.
         * Print an error message and stop.
         */
         clnt_pcreateerror(host);
         exit(1);
    }

    file = fopen(name, "wb");

    /*
     * Call the remote procedure readdir on the server
     */
    while (1) {
        req.start = total_bytes;
        result = retrieve_file_1(&req, clnt);
        if (result == NULL) {
            /*
             * An RPC error occurred while calling the server.
             * Print error message and stop.
             */
            clnt_perror(clnt, host);
            exit(1);
        }

        /*
         * Okay, we successfully called the remote procedure.
         */
        if (result->errno != 0) {
            /*
             * A remote system error occurred.
             * Print error message and stop.
             */
            errno = result->errno;
            perror(name);
            exit(1);
        }

        /*
         * Successfully got a chunk of the file.
         * Write into our local file.
         */
        write_bytes = fwrite(result->readfile_res_u.chunk.data, 1, result->readfile_res_u.chunk.bytes, file);
        total_bytes += result->readfile_res_u.chunk.bytes;
        if (result->readfile_res_u.chunk.bytes < MAXLEN) 
            break;
    }

    fclose(file);

    return 0;
}

int put_file(char *host, char *name)
{
    CLIENT *clnt;
    char data[1024];
    int total_bytes = 0, read_bytes;
    int *result;
    chunksend chunk;
    FILE *file;

    /*
     * Create client handle used for calling FTPPROG on
     * the server designated on the command line. Use
     * the tcp protocol when contacting the server.
     */
    clnt = clnt_create(host, FTPPROG, FTPVER, "tcp");
    if (clnt == NULL) {
        /*
         * Couldn't establish connection with server.
         * Print error message and stop.
         */
         clnt_pcreateerror(host);
         exit(1);
    }

    file = fopen(name, "r");

    chunk.name = name;

    /*
     * Call the remote procedure readdir on the server
     */
    while (1) {
        read_bytes = fread(data, 1, MAXLEN, file);
        total_bytes += read_bytes;

        read_bytes = fread(chunk.data, 1, MAXLEN, file);
        chunk.bytes = read_bytes;
        result = send_file_1(&chunk, clnt);

        if (result == NULL) {
            /*
             * An RPC error occurred while calling the server.
             * Print an error message and stop.
             */
            clnt_perror(clnt, host);
            exit(1);
        }

        /*
         * Okay, we successfully called the remote procedure.
         */
        if (*result != 0) {
            /*
             * A remote system error occurred.
             * Print an error message and stop.
             */
            errno = *result;
            perror(name);
            exit(1);
        }

        /*
         * Successfully got a chunk of the file.
         * Write into our local file. and complete
         */
        if (read_bytes < MAXLEN) 
            break;
    }

    fclose(file);

    return 0;
}

int read_command(char *host)
{
    char command[MAXLEN], filepath[MAXLEN];

    printf("> ");
    fflush(stdin);
    scanf("%s %s", command, filepath);

    if (strcmp(command, "get") == 0) {
        return get_file(host, filepath);
    } else if(strcmp(command, "put") == 0){
        return put_file(host, filepath);
    } else if(strcmp(command, "exit") == 0){
        exit(0);
    } else {
        return -1;
    }
}

int main(int argc, char *argv[])
{
   int result;

   if (argc != 2) {
        fprintf(stderr, "usage: %s host\n", argv[0]);
        exit(1);
   }

   while(TRUE) {
       result = read_command(argv[1]);
   }

   return 0;
}

Output :

You have defined your filechunk type to be an array. You can't assign one array to another array in C. Instead copy the data into the array.

That is the line ,

chunk.data = data;

But in this case you could read directly into that array,

Hence, This is your edited code

 read_bytes = fread(chunk.data, 1, MAXLEN, file);

Related Solutions

UNIX 1. Compile and run shell0.c file 2. Design and implement shell1.c program to handle "exit"...
UNIX 1. Compile and run shell0.c file 2. Design and implement shell1.c program to handle "exit" command to terminate the program. That is, if the user input-string is "exit", then the program terminates. 3.Design and Implement shell2.c to implement a signal handler to handle ctrl+C (SIGINT) as listed below             void sig_int(int signo) { printf("\nCaught SIGINT!\n"); } Here is shell0.c file shell0.c /* * shell0.c * running in loop to read input string (command) to be processed * To exit,...
Program in C Make both a SOURCE AND HEADER FILE WITH FUNCTIONS to run the program....
Program in C Make both a SOURCE AND HEADER FILE WITH FUNCTIONS to run the program. Input data from csv file. Two files. grades.c and grades.h Thank you data.csv file Mark Prest,37468,36,113,In Person Andy Joe,6785923,19,98,Online Caden Miller,237741,20,70.1,In Person Luke Jr,2347878,18,45.9,In Online Ally Rogers,8467483,30,89.99,Online Maya Jank,5674930,30,90,In Person Expected output Name: Mark Prest ID: 37468 Age: 36 Grade: 113.00 Attending: In Person Name: Andy Joe ID: 6785923 Age: 19 Grade: 98.00 Attending: Online Name: Caden Miller ID: 237741 Age: 20 Grade: 70.10...
Write a C program to run on unix to read a text file and print it...
Write a C program to run on unix to read a text file and print it to the display. It should count of the number of words in the file, find the number of occurrences of a substring, and take all the words in the string and sort them (ASCII order). You must use getopt to parse the command line. There is no user input while this program is running. Usage: mywords [-cs] [-f substring] filename • The -c flag...
WRITE A C++ PROGRAM TO IMPLEMENT THE CONCEPT OF INDEX (Create index in text file)
WRITE A C++ PROGRAM TO IMPLEMENT THE CONCEPT OF INDEX (Create index in text file)
Program Language C++ How do I take lines of string from an input file, and implement...
Program Language C++ How do I take lines of string from an input file, and implement them into a stack using a double linked list? Example input, command.txt, and output file. Ex: Input.txt postfix: BAC-* prefix:+A*B/C-EF postfix:FE-C/B*A+ postfix:AB-C-D/ postfix:AB-CF*-D / E+ Command.txt printList printListBackwards Output.txt List: postfix:BAC-* prefix:+A*B/C-EF postfix:FE-C/B*A+ postfix:AB-C-D/ postfix:AB-CF*-D/E+ Reversed List: postfix:AB-CF*-D/E+ postfix:AB-C-D/ postfix:FE-C/B*A+ prefix:+A*B/C-EF postfix:BAC-*
C programming - Implement a dynamic array, please read and implement the dynarray.c file with what...
C programming - Implement a dynamic array, please read and implement the dynarray.c file with what is given dynarray.h /* * This file contains the definition of the interface for the dynamic array * you'll implement. You can find descriptions of the dynamic array functions, * including their parameters and their return values, in dynarray.c. You * should not modify anything in this file. */ #ifndef __DYNARRAY_H #define __DYNARRAY_H /* * Structure used to represent a dynamic array. */ struct...
C++ Write a program that prompts for a file name and then reads the file to...
C++ Write a program that prompts for a file name and then reads the file to check for balanced curly braces, {; parentheses, (); and square brackets, []. Use a stack to store the most recent unmatched left symbol. The program should ignore any character that is not a parenthesis, curly brace, or square bracket. Note that proper nesting is required. For instance, [a(b]c) is invalid. Display the line number the error occurred on. These are a few of the...
I am writing a shell program in C++, to run this program I would run it...
I am writing a shell program in C++, to run this program I would run it in terminal like the following: ./a.out "command1" "command2" using the execv function how to execute command 1 and 2 if they are stored in argv[1] and argv[2] of the main function?
Write and test a C program to implement Bubble Sort. . In your C program, you...
Write and test a C program to implement Bubble Sort. . In your C program, you should do: Implement the array use an integer pointer, get the size of the array from standard input and use the malloc function to allocate the required memory for it. Read the array elements from standard input. Print out the sorted array, and don’t forget to free the memory. Debug your program using Eclipse C/C++ CDT.
Write a C++ program that creates a file called Readings.txt. Inside the file, your program must...
Write a C++ program that creates a file called Readings.txt. Inside the file, your program must create a list. The list is composed of integer double pairs. There is one pair per line. The integers are in sequence (0, 1, 2, 3, ...) beginning with zero and ending with some random value between 512 and 1024. The doubles should be random values between 50.000 and 90.000. The doubles only have 3 decimal places. The file should look like this (of...
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT