We do not want to retain zombie processes because they occupy the kernel space and eventually lead to depletion of the city's resources. To prevent sub-processes from becoming botnets, all sub-processes generated by fork must be wait.
# Include " Unp. h "
Int
Main ( Int Argc, Char ** Argv)
{
Int Listenfd, connfd;
Pid_t childpid;
Socklen_t clilen;
Struct Sockaddr_in cliaddr, servaddr;
Void Sig_chld ( Int );
Listenfd = socket (af_inet, sock_stream, 0 );
Bzero (& servaddr, Sizeof (Servaddr ));
Servaddr. sin_family = af_inet;
Servaddr. sin_addr.s_addr = htonl (inaddr_any );
Servaddr. sin_port = htons (serv_port );
BIND (listenfd, (Sa *) & servaddr, Sizeof (Servaddr ));
Listen (listenfd, listenq );
/* Add the following function call after the listen call. This function must be completed before the first sub-process of fork, and only once */
Signal (sigchld, sig_chld );
For (;;){
Clilen = Sizeof (Cliaddr );
Connfd = accept (listenfd, (Sa *) & cliaddr, & clilen );
If (Childpid = fork () = 0 ){ /* Child Process */
Close (listenfd ); /* Close listening socket */
Str_echo (connfd ); /* Process the request */
Exit ( 0 );
}
Close (connfd ); /* Parent closes connected socket */
}
}
Sig_chld Function:
# Include"Unp. h"
Void
Sig_chld (IntSigno)
{
Pid_t PID;
IntStat;
PID = wait (& Stat );
Printf ("Child % d terminated \ n", Pid );
Return;
}
Server:
Zhaoxj $ make tcpserv02
Gcc-I ../lib-g-O2-d_reentrant-wall-c-o tcpserv02.o tcpserv02.c
Gcc-I ../lib-g-O2-d_reentrant-wall-O tcpserv02 tcpserv02.o sigchldwait. O ../libunp. A-lpthread
Zhaoxj $./tcpserv02 &
[3] 15339
Client (open another terminal ):
Zhaoxj $./tcpcli01 127.0.0.1
Hi
Hi
^ D <CTR-D> end the customer terminal
The server displays the following information:
Child 15343 terminated
Specific process:
1. type the EOF character to terminate the customer. The customer TCP sends a fin to the server, and the server returns an ACK.
2. After receiving fin, the server sends an EOF to Readline in the sub-process blocking and the sub-process stops.
3. When a child process is terminated, A sigchld signal is generated and sent to the parent process. The parent process is blocking the Accept call. When the sig_chld function is executed, its wait call obtains the sub-process PID and termination.
Status, and then printf calls
Wait and waitpid functions (apue Process Control)
.....