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

C programming Write a pair of client and server programs in that allow the clien

ID: 3581744 • Letter: C

Question

C 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);
}