I am attempting an extra credit assignment for a summer course. The question says : "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."
I have tried revising the codes, however, it will not show me the directory contents. All I get after running the server, then running the client to connect to the server is the statement "This server has been contacted 1 time. n = 39. n = 0." Any ideas where I am going wrong?
*The original code was provided by the professor. These are my modified versions.

/* client.c - code for example client program that uses TCP */
#ifndef unix
#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 <arpa/inet.h>
#include <netdb.h>
#endif
#include <stdio.h>
#include <string.h>
#define PROTOPORT 5193 /* default protocol port number */
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 */
    struct dirent *en;
    DIR *dr;
    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\n",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\n", 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\n");
        exit(1);
    }
    /* Connect the socket to the specified server. */
    if (connect(sd, (struct sockaddr *)&sad, sizeof(sad)) < 0) {
        fprintf(stderr,"connect failed\n");
        exit(1);
    }
    /* Repeatedly read data from socket and write to user.s screen. */
    n = recv(sd, buf, sizeof(buf), 0);
    while (n > 0) {
        write(1,buf,n);
        printf("n: %d\n", n);
        n = recv(sd, buf, sizeof(buf), 0);
    }
        printf("n: %d\n", n);
        dr = opendir("./");
        if (dr != NULL) {
            while (en = readdur(dp))
                puts (en -> d_name);
        (void) closedir(dp);
                }
        else
            perror("Couldn't open directory");
        return 0;

            /* Close the socket. */
    closesocket(sd);
    /* Terminate the client program gracefully. */
    exit(0);
}

/* server.c - code for example server program that uses TCP */
#ifndef unix
#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>
#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 */
    struct dirent *en;
    DIR *dr;
    char buf[1000]; /* buffer for string the server sends */
#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\n",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\n");
        exit(1);
    }
    /* Bind a local address to the socket */
    if (bind(sd, (struct sockaddr *)&sad, sizeof(sad)) < 0) {
        fprintf(stderr,"bind failed\n");
        exit(1);
    }
    /* Specify size of request queue */
    if (listen(sd, QLEN) < 0) {
        fprintf(stderr,"listen failed\n");
        exit(1);
    }
    /* 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\n");
            exit(1);
        }
        visits++;
        sprintf(buf,"This server has been contacted %d time%s\n",
                visits,visits==1?".":"s.");
        send(sd2,buf,strlen(buf),0);
    dr = opendir("./");
    if (dr != NULL) {
        while (en = readdur(dp)) {
                puts (en -> d_name);}
        (void) closedir(dp);
                }
        else
            perror("Couldn't open directory");
        return 0;

        closesocket(sd2);
    }
}

Recommended Answers

All 3 Replies

You can start by putting in more debugging output where you think it's not working.

Also you can write antoher app that does that directory work and learn how to get that working on its own. In psuedocode:
Read a string from the user.
Get the directory and print it back to the user.

I think you are also missing a terminating brace for the server while (1) loop. You are also missing a return value in server main. Even though the server never terminates, this should cause all current compilers to complain.

Also readdir() is probably meant instead of readdur(). The compiler cannot miss this.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.