The book UNIX Network Programming comes with many small and exquisite programs. When I read this book, rewrite the code in the book according to your own understanding (most of them are on the copybook) to deepen your understanding (it's too difficult to read a book, huh, huh ). This example is successfully tested on ubuntu10.04.
PS: The program uses the declaration of the wrap function (the first character is an upper-case function) and constant (all letters are uppercase constants). In the my_unp.h file, it is defined in unp_base.c and unp_thread.c, address: http://blog.csdn.net/aaa20090987/article/details/8096701
Program Introduction: this is a traditional multi-process server model. When a client connects to the server, the server generates a sub-process to communicate with the client. This communication mechanism is efficient, and the maximum number of connections is limited by the maximum number of sub-processes in the system. But its implementation is relatively simple, so it is popular in early UNIX systems.
Code:
# Include "my_unp.h" Void str_echo (INT sockfd) {ssize_t N; char Buf [maxline]; again: // read data from the socket, write to buffer // write the data in buffer to socket while (n = read (sockfd, Buf, maxline)> 0) writen (sockfd, Buf, n); // No data is written or successfully read due to signal interruption. If (n <0 & errno = eintr) goto again; else if (n <0) error_quit ("str_echo: read error");} // capture and process the sigchld signal void sig_child (INT signo) {pid_t PID; int Stat; while (pid = waitpid (-1, & stat, wnohang)> 0) printf ("child % d terminated \ n", pid); return ;} int main (void) {int listenfd, connfd; pid_t childpid; socklen_t clilen; char buff [maxline]; struct sockaddr_in cliaddr, servaddr; // create the socket listenfd = socket (af_inet, sock_stream, 0) for TCP protocol; memset (& servaddr, 0, sizeof (servaddr); servaddr. sin_family = af_inet; servaddr. sin_addr.s_addr = htonl (inaddr_any); servaddr. sin_port = htons (serv_port); // link the socket and socket address structures to bind (listenfd, (Sa *) & servaddr, sizeof (servaddr )); // start listening to the listenq port listen (listenfd, listenq); // process the sigchld signal to prevent the sub-process from becoming a dead process signal (sigchld, sig_child); While (1) {clilen = sizeof (cliaddr); // receives a connection from the client // sleep the program if no connection request is sent, until there is a connection request -- this is a feature of the accept function // The accept function returns a descriptor. This socket (connfd) is used to communicate with the connected customer. connfd = accept (listenfd, (Sa *) & cliaddr, & clilen); If (connfd <0) {// accetp () is a slow system call, which is interrupted when a signal is generated, // set the errno variable to eintr. In this case, call if (errno = eintr) continue; else error_quit ("Accept error");} // to generate a sub-process, let it process communications with (a client) childpid = fork (); If (childpid = 0) {close (listenfd); str_echo (connfd); Return 0 ;} // output the IP address and port number of the client, and the PID printf ("connection from % s, port % d) of the processing (sub) process. process with clild % d \ n ", inet_ntop (af_inet, (void *) & cliaddr. sin_addr, buff, sizeof (buff), ntohs (cliaddr. sin_port), childpid); // the communication with the client is handled by the sub-process, so close the socket (connfd);} return 0 ;}
Its Supporting client is here: http://blog.csdn.net/aaa20090987/article/details/8462262