Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

shell programming Write a pair of client and server programs in that allow the c

ID: 3577007 • Letter: S

Question

shell programming

Write a pair of client and server programs in that allow the client to download a file from the server.

First, the user on the server's side starts the server as follows.

./fileserver 6018

, where 6018 is the port number where the server will be waiting for connection.

(Use your own unique port number (1024-49151) to avoid conflict with another user on the same computer.)

Then, the user on the client side starts the client as follows.

./fileclient remoteservername remotefilename 6018

, where remoteservername is the domain name of the remote server's computer, remotefilename is the name of the file on the server's side, and 6018 is the port number where the server is waiting.

The client sends the remotefilename to the server, which, then, opens the file, and sends its contents back to the client. The client should create a file with the same name based on the contents received from the server. In order to avoid confusion, execute the client and the server in separate directories.

You may assume that no error occurs in the client server interaction.

Submit fileclient.c and fileserver.c.

Explanation / Answer

fileclient.c

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <string.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <netdb.h>

#include <libgen.h>

#include <unistd.h>

//fileclient ip_of_fileserver port_to_connect file_to_send

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

   int sockfd, portnum, s, flen, size;

   char *server_ip, *file_addr, *filename;

   struct sockaddr_in serv_addr;

   FILE *fp;

   //checking the arg count

   if (argc < 4) {

       fprintf(stderr,"insufficient arguments ");

       exit(0);

   }

   //fetch the arguments

   server_ip = argv[1];

   file_addr = argv[3];

   filename = basename(file_addr);

   portnum = atoi(argv[2]);

   sockfd = socket(AF_INET, SOCK_STREAM, 0);

   if (sockfd < 0){

        fprintf(stderr,"ERROR opening socket");

        exit(0);

    }

    printf("sending file %s to %s ",file_addr,server_ip);

   //fill in the socket

   bzero((char *) &serv_addr, sizeof(serv_addr));

   serv_addr.sin_family = AF_INET;

   serv_addr.sin_port = htons(portnum);

   s = inet_pton(AF_INET, server_ip, &(serv_addr.sin_addr));

   if (s <= 0) {

        if (s == 0)

            fprintf(stderr, "Not in presentation format");

        else

            fprintf(stderr,"inet_pton");

        exit(EXIT_FAILURE);

    }

    //connect to the server

    if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0){

        fprintf(stderr, "ERROR connecting");

        exit(0);

    }

    else{

       printf("connected to %s on tcp %d ", server_ip, portnum);

    }

    //open the file

    fp = fopen(file_addr, "rb");

    if(fp == NULL){

       printf("can't open file %s ", file_addr);

        exit(0);

    }

    else

       printf("opened file %s ", file_addr);

    //get file size

   fseek(fp, 0L, SEEK_END);

   size = ftell(fp);

   fseek(fp, 0L, SEEK_SET);

    //count the name string length

    flen = strlen(filename);

    flen++; //account for the null terminator

    //send header info

    write(sockfd, &flen, sizeof(int));

    write(sockfd, filename, flen);

    //send the file

    printf("start sending file ");

    int fd = fileno(fp);

    sendfile(sockfd, fd, NULL, size);

    printf("finish sending file ");

    printf("closing file %s ", file_addr);

    fclose(fp);

    printf("closing socket ");

    close(sockfd);

    return 0;

}

fileserver.c

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <arpa/inet.h>

#include <netinet/in.h>

#include <unistd.h>

static int BUFFER_SIZE = 256;

//fileserver ip_to_bind port_to_listen

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

   int sockfd, newsockfd, portnum, s, clilen, flen, data_received;

   char *ip_addr;

   struct sockaddr_in serv_addr, cli_addr;

   char buffer[BUFFER_SIZE];

   FILE *fp;

   //check the arg count

   if (argc < 2) {

       fprintf(stderr, "insufficient ammount of arguments ");

       exit(0);

   }

   //fetch the arguments

   portnum = atoi(argv[2]);

   ip_addr = argv[1];

   //create the socket

   sockfd = socket(AF_INET, SOCK_STREAM, 0);

   if (sockfd < 0){

        printf("can't open socket at %s:%d", ip_addr, portnum);

        exit(0);

    }

    else

       printf("opening passive socket at %s:%d ", ip_addr, portnum);

    bzero((char *) &serv_addr, sizeof(serv_addr));

    serv_addr.sin_family = AF_INET;

    serv_addr.sin_port = htons(portnum);

    s = inet_pton(AF_INET, ip_addr, &(serv_addr.sin_addr));

   if (s <= 0) {

        if (s == 0)

            fprintf(stderr, "Not in presentation format");

        else

            fprintf(stderr,"inet_pton");

        exit(EXIT_FAILURE);

    }

   if(bind(sockfd, (struct sockaddr *) &serv_addr,

       sizeof(serv_addr)) < 0){

       fprintf(stderr, "ERROR on binding");

           exit(0);

       }

    printf("Listening for connection ");

    listen(sockfd,5);

    clilen = sizeof(cli_addr);

   newsockfd = accept(sockfd,

   (struct sockaddr *) &cli_addr, (socklen_t *) &clilen);

   if(newsockfd<=0){

       fprintf(stderr, "Not in presentation format");

       exit(0);

   }

else{

       printf("accepted connection from client %s ", ip_addr);

   }

   //get the filename length

   read(newsockfd, &flen, sizeof(int));

   //get the filename

   char filename[flen];

   read(newsockfd, filename, flen);

   //create the new file to be copied into

   fp = fopen(filename, "ab");

   if(fp == NULL){

       printf("Can't open%s ", filename);

       exit(0);

   }

   else

       printf("opened file %s to write byte stream ", filename);

   bzero(buffer, BUFFER_SIZE);

   printf("start receiving byte stream ");

   while((data_received = read(newsockfd, buffer, BUFFER_SIZE)) >0){

       fwrite(buffer, 1, data_received, fp);

       bzero(buffer, BUFFER_SIZE);

   }

   printf("byte stream finished ");

   printf("closing file %s ", filename);

   fclose(fp);

   printf("closing socket");

   close(newsockfd);

   close(sockfd);

   exit(0);

}