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);
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.