Previously, we have compiled a code http://www.bkjia.com/kf/201201/116006.html. now we have added a bit of code for this type of operating system!
We all know that fork () is available only in Unix/Linux operating systems! Because they do not have a thread. They only have sub-processes.
To use fork, you must use waitpid ()!
Waitpid function prototype:
# Include <sys/types. h>/* define the pid_t type */
# Include <sys/wait. h>
Pid_twaitpid (pid_tpid, int * status, int options );
When the pid parameter is-1, there is no limit to wait for any sub-process to exit. At this time, waitpid and wait play the same role.
The parameter status is set to NULL.
The options parameter provides some additional options to control the waitpid. The WNOHANG Constant indicates that the waitpid will be returned immediately even if no sub-process exits and will not wait forever as wait does.
We want to use waitpid () only when it is sent!
In this case, we need another function sigaction ().
Sigaction function prototype:
# Include <signal. h>
Int sigaction (int signum, const struct sigaction * act, struct sigaction * oldact );
When the signum parameter is SIGCHLD, the call is performed only when the sub-process is stopped or exited.
The act parameter is a pointer to the sigaction structure.
The oldact parameter is generally abolished.
We can set three member variables, namely, sa_handler, sa_mask, and sa_flags, In the sigaction structure!
The following is an example:
/**
* Version: 0.2
*
* Description: Add signal
*
*/
# Include <stdio. h>
# Include <string. h>
# Include <sys/types. h>
# Include <sys/socket. h>
# Include <netdb. h>
# Include <arpa/inet. h>
# Include <signal. h>
# Include <sys/wait. h>
# Include <stdlib. h>/* exit declare */
# Include <unistd. h>/* fork declare */
# Define SERVPORT "2349"
Void sigchild_handler ()
{
While (waitpid (-1, NULL, WNOHANG)> 0 );
}
Int main (int argc, char * argv [])
{
Struct addrinfo hints, * res;
Int status;
Int sockfd;
Int connFd;
/* Struct sockaddr_in cliAddr; Only IPv4 */
Struct sockaddr_storage clientAddr;/* both IPv4 and IPv6 */
Struct sigaction sa;
Int sendSta;
Char * msg;
If (argc! = 2 ){
Fprintf (stderr, "Usage: Not found Read File ");
Return 1;
}
Memset (& hints, 0, sizeof (hints ));
Hints. ai_family = AF_UNSPEC;
Hints. ai_socktype = SOCK_STREAM;
Hints. ai_flags = AI_PASSIVE;
Status = getaddrinfo (NULL, SERVPORT, & hints, & res );
If (status! = 0 ){
Fprintf (stderr, "getaddrinfo, fail! ");
Return 2;
}
Sockfd = socket (res-> ai_family, res-> ai_socktype, res-> ai_protocol );
Bind (sockfd, res-> ai_addr, res-> ai_addrlen );
Listen (sockfd, 5 );
Printf ("========= Please Wait Client ===========\ n ");
/* Struct sigaction notes from POSIX:
*
* (1) Routines stored in sa_handler shoshould take a single int
* Their argument although the POSIX standard does not require this.
* (2) The fields sa_handler and sa_sigaction may overlap, and a conforming
* Application shoshould not use both simultaneously.
*/
Sa. sa_handler = sigchild_handler;
Sigemptyset (& sa. sa_mask);/* Additional set of signals to be blocked */
/* During execution of signal-catching function .*/
Sa. sa_flags = SA_RESTART;/* Special flags to affect behavior of signal */
/* SA_RESTART 0x10000000 // Restart syscall on signal return */
If (sigaction (SIGCHLD, & sa, NULL) =-1) {/* SIGCHLD 20 // to parent on child stop or exit */
Fprintf (stderr, "sigaction fail! ");
Exit (3 );
}
While (1) {// loop forever!
Char ipstr [INET_ADDRSTRLEN];
Void * addr;
Int len = sizeof (clientAddr );
ConnFd = accept (sockfd, (struct sockaddr *) & clientAddr, & len );
/* View Client IP */
Struct sockaddr_in * ipv4 = (struct sockaddr_in *) & clientAddr;
Addr = & (ipv4-> sin_addr );
Inet_ntop (AF_INET, addr, ipstr, sizeof (ipstr ));
Printf ("client: % s \ n", ipstr );
If (! Fork ()){
Close (sockfd);/* child doesn't need the listener */
/* Copy Data */
Msg = "The server simply displays a message! ";
SendSta = send (connFd, msg, strlen (msg), 0 );
If (sendSta =-1)
Fprintf (stderr, "send fail! ");
Close (connFd );
Exit (0 );
}
Close (connFd );
}
Close (sockfd );
Return 0;
}
/**
* Version: 0.2
*
* Description: Add signal
*
*/
# Include <stdio. h>
# Include <string. h>
# Include <sys/types. h>
# Include <sys/socket. h>
# Include <netdb. h>
# Include <arpa/inet. h>
# Include <signal. h>
# Include <sys/wait. h>
# Include <stdlib. h>/* exit declare */
# Include <unistd. h>/* fork declare */
# Define SERVPORT "2349"
Void sigchild_handler ()
{
While (waitpid (-1, NULL, WNOHANG)> 0 );
}
Int main (int argc, char * argv [])
{
Struct addrinfo hints, * res;
Int status;
Int sockfd;
Int connFd;
/* Struct sockaddr_in cliAddr; Only IPv4 */
Struct sockaddr_storage clientAddr;/* both IPv4 and IPv6 */
Struct sigaction sa;
Int sendSta;
Char * msg;
If (argc! = 2 ){
Fprintf (stderr, "Usage: Not found Read File ");
Return 1;
}
Memset (& hints, 0, sizeof (hints ));
Hints. ai_family = AF_UNSPEC;
Hints. ai_socktype = SOCK_STREAM;
Hints. ai_flags = AI_PASSIVE;
Status = getaddrinfo (NULL, SERVPORT, & hints, & res );
If (status! = 0 ){
Fprintf (stderr, "getaddrinfo, fail! ");
Return 2;
}
Sockfd = socket (res-> ai_family, res-> ai_socktype, res-> ai_protocol );
Bind (sockfd, res-> ai_addr, res-> ai_addrlen );
Listen (sockfd, 5 );
Printf ("========= Please Wait Client ===========\ n ");
/* Struct sigaction notes from POSIX:
*
* (1) Routines stored in sa_handler shoshould take a single int
* Their argument although the POSIX standard does not require this.
* (2) The fields sa_handler and sa_sigaction may overlap, and a conforming
* Application shoshould not use both simultaneously.
*/
Sa. sa_handler = sigchild_handler;
Sigemptyset (& sa. sa_mask);/* Additional set of signals to be blocked */
/* During execution of signal-catching function .*/
Sa. sa_flags = SA_RESTART;/* Special flags to affect behavior of signal */
/* SA_RESTART 0x10000000 // Restart syscall on signal return */
If (sigaction (SIGCHLD, & sa, NULL) =-1) {/* SIGCHLD 20 // to parent on child stop or exit */
Fprintf (stderr, "sigaction fail! ");
Exit (3 );
}
While (1) {// loop forever!
Char ipstr [INET_ADDRSTRLEN];
Void * addr;
Int len = sizeof (clientAddr );
ConnFd = accept (sockfd, (struct sockaddr *) & clientAddr, & len );
/* View Client IP */
Struct sockaddr_in * ipv4 = (struct sockaddr_in *) & clientAddr;
Addr = & (ipv4-> sin_addr );
Inet_ntop (AF_INET, addr, ipstr, sizeof (ipstr ));
Printf ("client: % s \ n", ipstr );
If (! Fork ()){
Close (sockfd);/* child doesn't need the listener */
/* Copy Data */
Msg = "The server simply displays a message! ";
SendSta = send (connFd, msg, strlen (msg), 0 );
If (sendSta =-1)
Fprintf (stderr, "send fail! ");
Close (connFd );
Exit (0 );
}
Close (connFd );
}
Close (sockfd );
Return 0;
}
End.
From the column xiaobin_HLJ80