18.5 UICI Implementations of Different Server Strategies

Team-FLY

Program 18.1 shows a serial-server program that copies information from a client to standard output, using the UICI library. The server takes a single command-line argument specifying the number of the well-known port on which it listens. The server obtains a listening file descriptor for the port with u_open and then displays its process ID. It calls u_accept to block while waiting for a client request. The u_accept function returns a communication file descriptor for the client communication. The server displays the name of the client and uses copyfile of Program 4.6 on page 100 to perform the actual copying. Once it has finished the copying, the server closes the communication file descriptor, displays the number of bytes copied , and resumes listening.

Program 18.1 server.c

A serial server implemented using UICI .

 #include <limits.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include "restart.h" #include "uici.h" int main(int argc, char *argv[]) {    int bytescopied;    char client[MAX_CANON];    int communfd;    int listenfd;    u_port_t portnumber;    if (argc != 2) {       fprintf(stderr, "Usage: %s port\n", argv[0]);       return 1;    }    portnumber = (u_port_t) atoi(argv[1]);    if ((listenfd = u_open(portnumber)) == -1) {       perror("Failed to create listening endpoint");       return 1;    }    fprintf(stderr, "[%ld]:waiting for the first connection on port %d\n",                     (long)getpid(), (int)portnumber);    for ( ; ; ) {       if ((communfd = u_accept(listenfd, client, MAX_CANON)) == -1) {          perror("Failed to accept connection");          continue;       }       fprintf(stderr, "[%ld]:connected to %s\n", (long)getpid(), client);       bytescopied = copyfile(communfd, STDOUT_FILENO);       fprintf(stderr, "[%ld]:received %d bytes\n", (long)getpid(), bytescopied);       if (r_close(communfd) == -1)          perror("Failed to close communfd\n");    } } 
Exercise 18.9

Under what circumstances does a client cause the server in Program 18.1 to terminate?

Answer:

The server executes the first return statement if it is not started with a single command-line argument. The u_open function creates a communication endpoint associated with a port number. The u_open function fails if the port is invalid, if the port is in use, or if system resources are not available to support the request. At this point, no clients are involved. Once the server has reached u_accept , it does not terminate unless it receives a signal. A client on a remote machine cannot cause the server to terminate. A failure of u_accept causes the server to loop and try again. Notice that I/O errors cause copyfile to return, but these errors do not cause server termination.

Program 18.2 implements the parent-server strategy. The parent accepts client connections and forks a child to call copyfile so that the parent can resume waiting for connections. Because the child receives a copy of the parent's environment at the time of the fork, it has access to the private communication channel represented by communfd .

Exercise 18.10

What happens if the client name does not fit in the buffer passed to u_accept ?

Answer:

The implementation of u_accept does not permit the name to overflow the buffer. Instead, u_accept truncates the client name. (See Section 18.7.6.)

Exercise 18.11

What happens if after the connection is made, you enter text at standard input of the server?

Answer:

The server program never reads from standard input, and what you type at standard input is not sent to the remote machine.

Exercise 18.12

Program 18.2 uses r_close and r_waitpid from the restart library. How does this affect the behavior of the program?

Answer:

Functions in the restart library restart the corresponding function when the return value is “1 and errno is EINTR . This return condition occurs when the signal handler of a caught signal returns. Program 18.2 does not catch any signals, so using the restarted versions is not necessary. We use the functions from the restart library to make it easier to add signal handling capability to the programs.

Program 18.2 serverp.c

A server program that forks a child to handle communication .

 #include <errno.h> #include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include "restart.h" #include "uici.h" int main(int argc, char *argv[]) {    int bytescopied;    pid_t child;    char client[MAX_CANON];    int communfd;    int listenfd;    u_port_t portnumber;    if (argc != 2) {       fprintf(stderr, "Usage: %s port\n", argv[0]);       return 1;    }    portnumber = (u_port_t) atoi(argv[1]);    if ((listenfd = u_open(portnumber)) == -1) {       perror("Failed to create listening endpoint");       return 1;    }    fprintf(stderr, "[%ld]: Waiting for connection on port %d\n",                     (long)getpid(), (int)portnumber);    for ( ; ; ) {       if ((communfd = u_accept(listenfd, client, MAX_CANON)) == -1) {          perror("Failed to accept connection");          continue;       }       fprintf(stderr, "[%ld]:connected to %s\n", (long)getpid(), client);       if ((child = fork()) == -1) {          perror("Failed to fork a child");          continue;       }       if (child == 0) {                                         /* child code */          if (r_close(listenfd) == -1) {             fprintf(stderr, "[%ld]:failed to close listenfd: %s\n",                              (long)getpid(), strerror(errno));             return 1;          }          bytescopied = copyfile(communfd, STDOUT_FILENO);          fprintf(stderr, "[%ld]:received %d bytes\n",                           (long)getpid(), bytescopied);          return 0;       }       if (r_close(communfd) == -1)                             /* parent code */          fprintf(stderr, "[%ld]:failed to close communfd: %s\n",                           (long)getpid(), strerror(errno));       while (r_waitpid(-1, NULL, WNOHANG) > 0)  ;         /* clean up zombies */    } } 
Team-FLY


Unix Systems Programming
UNIX Systems Programming: Communication, Concurrency and Threads
ISBN: 0130424110
EAN: 2147483647
Year: 2003
Pages: 274

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net