The server that was developed in previous posting Using Standard I/O on Sockets has been modified in this section to handle multiple clients by means of a fork(2) system call. Listing 11.2 shows the listing of the modified rpnsrv.c module. All other source modules remain the same as they appeared in the previous post.
The following session shows how to compile and to start the server in the background:
[sgupta@rhel54x64 rpn-main-server]$
[sgupta@rhel54x64 rpn-main-server]$ gcc -c -D_GNU_SOURCE -Wall -Wreturn-type rpnsrv.c [sgupta@rhel54x64 rpn-main-server]$ gcc -c -D_GNU_SOURCE -Wall -Wreturn-type rpneng.c [sgupta@rhel54x64 rpn-main-server]$ gcc -c -D_GNU_SOURCE -Wall -Wreturn-type mkaddr.c gcc [sgupta@rhel54x64 rpn-main-server]$ rpnsrv.o rpneng.o mkaddr.o -o rpnsrv -Igmp
[sgupta@rhel54x64 rpn-main-server]$ ./rpnsrv '*:9090' & [2] 915
[sgupta@rhel54x64 rpn-main-server]$
After the server has been started, you can use telnet from multiple xterm windows to try out the server simultaneously. If you are not running the X Window system, you can use various virtual console sessions to accomplish the same effect.
The principle changes to the module are as follows:
• The
Understanding
Process Termination Processing
The one
complication that the fork(2) function call inflicts upon the design of the
server is that it must process information about terminated processes. This is
very important, because when a child process
terminates, most of its resources are released. The rest of its resources are
released only when the parent process obtains the child process termination
status information.
The parent
process is notified of a child process termination by means of the signal SIGCHLD.
Now examine the steps that the parent server process uses when a child process
terminates:
- The signal SIGCHLD is raised by the kernel to indicate that the child process has terminated.
- The function sigchld_handler() is called (line 35), because the function was registered for the SIGCHLD signal.
- The sigchld_handler() executes a loop calling waitpid(2) until no more exit status information is available.
- The SIGCHLD handler is re-instated. This was necessary because the reliable signals interface was not used in order to keep the example program simple.
NOTE
In a production
mode server, only the reliable signal functions such as sigaction (2) should be
used. This was avoided in the example program to keep the source code simple.
CAUTION
Failure to call wait(2)
or waitpid(2) by the parent process after a fork(2) and the child process's
subsequent termination will result in zombie processes being left around until
the parent process terminates. This can tie up valuable system resources.
The reader is
encouraged to review the functions fork(2), waitpid(2), and signal(2), if necessary. These
are important aspects of this server design.
No comments:
Post a Comment