Modify the client.c and server.c program from Assignment 1 to add the following
ID: 3912510 • Letter: M
Question
Modify the client.c and server.c program from Assignment 1 to add the following function: when the client connects to the server, the client provides the name of a directory D to be retrieved in the server;
When the server receives the request, the server reads the name of the directory D, retrieves the contents from the directory D, and sends the contents back to the client.
The client, after receiving the contents from the server, prints out the content.
Hint: 1. Use opendir() to open a directory; use “man opendir” to check more details;
2. Use readdir() to read contents under a directory: use “man 3 readdir’ to check more details
3. Use closedir() to close a directory
Link to the client.C Code : https://pastebin.com/nn629s8Z
Link to the Server.C Code: https://pastebin.com/3WTeYcv7
Explanation / Answer
/* client.c - code for example client program that uses TCP */
//#ifndef unix
#ifdef _WIN32
#include <windows.h>
#include <winsock.h>
#else
#define closesocket close
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#endif
#include <stdio.h>
#include <string.h>
#define PROTOPORT 5193 /* default protocol port number */ //5193
extern int errno;
char localhost[] = "localhost"; /* default host name */
/*------------------------------------------------------------------------
* * Program: client
* *
* * Purpose: allocate a socket, connect to a server, and print all output
* * Syntax: client [ host [port] ]
* *
* * host - name of a computer on which server is executing
* * port - protocol port number server is using
* *
* * Note: Both arguments are optional. If no host name is specified,
* * the client uses "localhost"; if no protocol port is
* * specified, the client uses the default given by PROTOPORT.
* *
* *------------------------------------------------------------------------
* */
main(argc, argv)
int argc;
char *argv[];
{
struct hostent *ptrh; /* pointer to a host table entry */
struct protoent *ptrp; /* pointer to a protocol table entry */
struct sockaddr_in sad; /* structure to hold an IP address */
int sd; /* socket descriptor */
int port; /* protocol port number */
char *host; /* pointer to host name */
int n; /* number of characters read */
char buf[1000]; /* buffer for data from the server */
#ifdef WIN32
WSADATA wsaData;
WSAStartup(0x0101, &wsaData);
#endif
memset((char *)&sad,0,sizeof(sad)); /* clear sockaddr structure */
sad.sin_family = AF_INET; /* set family to Internet */
/* Check command-line argument for protocol port and extract */
/* port number if one is specified. Otherwise, use the default */
/* port value given by constant PROTOPORT */
if (argc > 2) { /* if protocol port specified */
port = atoi(argv[2]); /* convert to binary */
} else {
port = PROTOPORT; /* use default port number */
}
if (port > 0) /* test for legal value */
sad.sin_port = htons((u_short)port);
else { /* print error message and exit */
fprintf(stderr,"bad port number %s ",argv[2]);
exit(1);
}
/* Check host argument and assign host name. */
if (argc > 1) {
host = argv[1]; /* if host argument specified */
} else {
host = localhost;
}
/* Convert host name to equivalent IP address and copy to sad. */
ptrh = gethostbyname(host);
if ( ((char *)ptrh) == NULL ) {
fprintf(stderr,"invalid host: %s ", host);
exit(1);
}
memcpy(&sad.sin_addr, ptrh->h_addr, ptrh->h_length);
/* Map TCP transport protocol name to protocol number. */
if ( ((int)(ptrp = getprotobyname("tcp"))) == 0) {
fprintf(stderr, "cannot map "tcp" to protocol number");
exit(1);
}
/* Create a socket. */
sd = socket(PF_INET, SOCK_STREAM, ptrp->p_proto);
if (sd < 0) {
fprintf(stderr, "socket creation failed ");
exit(1);
}
/* Connect the socket to the specified server. */
if (connect(sd, (struct sockaddr *)&sad, sizeof(sad)) < 0) {
fprintf(stderr,"connect failed ");
exit(1);
}
printf("Enter Full Directory Name: ");
scanf("%s",buf);
// send scanned directory name to server
send(sd,buf,strlen(buf),0);
printf("Directory name:%s sent to server Waiting for contents ",buf);
/* Repeatedly read data from socket and write to user.s screen. */
n = recv(sd, buf, sizeof(buf), 0);
while (n > 0) {
// Print received contents on stdout file descriptor 1
write(1,buf,n);
printf(" ");
n = recv(sd, buf, sizeof(buf), 0);
}
// printf("Client socket closed n: %d ", n);
/* Close the socket. */
closesocket(sd);
/* Terminate the client program gracefully. */
exit(0);
}
/* server.c - code for example server program that uses TCP */
#ifdef _WIN32
//#define WIN32
#include <windows.h>
#include <winsock.h>
#else
#define closesocket close
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#endif
#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <sys/types.h>
#define PROTOPORT 5193 /* default protocol port number */
#define QLEN 6 /* size of request queue */
int visits = 0; /* counts client connections */
/*------------------------------------------------------------------------
* * Program: server
* *
* * Purpose: allocate a socket and then repeatedly execute the following:
* * (1) wait for the next connection from a client
* * (2) send a short message to the client
* * (3) close the connection
* * (4) go back to step (1)
* * Syntax: server [ port ]
* *
* * port - protocol port number to use
* *
* * Note: The port argument is optional. If no port is specified,
* * the server uses the default given by PROTOPORT.
* *
* *------------------------------------------------------------------------
* */
main(argc, argv)
int argc;
char *argv[];
{
struct hostent *ptrh; /* pointer to a host table entry */
struct protoent *ptrp; /* pointer to a protocol table entry */
struct sockaddr_in sad; /* structure to hold server.s address */
struct sockaddr_in cad; /* structure to hold client.s address */
int sd, sd2; /* socket descriptors */
int port; /* protocol port number */
int alen; /* length of address */
char buf[1000],dirname[1000]; /* buffer for string the server sends */
DIR *dir=NULL; //pointer to hold received directory name
struct dirent *dentry=NULL; // pointer to hold the directory content name
#ifdef WIN32
WSADATA wsaData;
WSAStartup(0x0101, &wsaData);
#endif
memset((char *)&sad,0,sizeof(sad)); /* clear sockaddr structure */
sad.sin_family = AF_INET; /* set family to Internet */
sad.sin_addr.s_addr = INADDR_ANY; /* set the local IP address */
/* Check command-line argument for protocol port and extract */
/* port number if one is specified. Otherwise, use the default */
/* port value given by constant PROTOPORT */
if (argc > 1) { /* if argument specified */
port = atoi(argv[1]); /* convert argument to binary */
} else {
port = PROTOPORT; /* use default port number */
}
if (port > 0) /* test for illegal value */
sad.sin_port = htons((u_short)port);
else { /* print error message and exit */
fprintf(stderr,"bad port number %s ",argv[1]);
exit(1);
}
/* Map TCP transport protocol name to protocol number */
if ( ((int)(ptrp = getprotobyname("tcp"))) == 0) {
fprintf(stderr, "cannot map "tcp" to protocol number");
exit(1);
}
/* Create a socket */
sd = socket(PF_INET, SOCK_STREAM, ptrp->p_proto);
if (sd < 0) {
fprintf(stderr, "socket creation failed ");
exit(1);
}
/* Bind a local address to the socket */
if (bind(sd, (struct sockaddr *)&sad, sizeof(sad)) < 0) {
fprintf(stderr,"bind failed ");
exit(1);
}
/* Specify size of request queue */
if (listen(sd, QLEN) < 0) {
fprintf(stderr,"listen failed ");
exit(1);
}
printf("Server listening for incoming connections... ");
/* Main server loop - accept and handle requests */
while (1) {
alen = sizeof(cad);
if ( (sd2=accept(sd, (struct sockaddr *)&cad, &alen)) < 0) {
fprintf(stderr, "accept failed ");
exit(1);
}
visits++;
int n = recv(sd2, dirname, sizeof(dirname), 0);
if(n == -1)
printf("Received no input from client ");
printf("Visit no: %d Directory name received:%s ",visits,dirname);
sprintf(buf,"This server has been contacted %d time%s ",
visits,visits==1?".":"s.");
send(sd2,buf,strlen(buf),0);
// open the received directory into a pointer
dir=opendir(dirname);
if(dir == NULL){
printf("Error opening the directory ");
}else{
printf("Directory %s opened successfully ",dirname);
}
// read each each entry in the directory and send the name to the client on the client's socket descriptor
while((dentry=readdir(dir))!=NULL){
printf("%s ",dentry->d_name);
send(sd2,dentry->d_name,strlen(dentry->d_name),0);
}
// close the opened directory pointer
closedir(dir);
closesocket(sd2);
}
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.