Linux client/server programming Paradigm-Apache Server (multi-process)

Source: Internet
Author: User
Tags signal handler

Introduction

This article writes a concurrent server (concurrent server) program that fork out a child process for each client request.

Attention

1. Signal Processing problems

For the same signal, according to the order of the signal is processed sequentially. The problem that may arise is that when the SIG1 signal is being processed, there are 2 or more SIG1 signals, which will only process 1 SIG1 signals after the original SIG1 signal is processed. therefore, for the same signal, there will be a signal substitution problem. after a son has retired, the program in the process of processing handler (), if at this time and back two sons, then there must be a son of resources not recovered, called the zombie process.

For different signals, priority is given to the latter, and the latter is processed back to the last one. For example, when SIG1 is being processed, the SIG2 is processed, SIG2 is handled first, and the SIG2 is processed, and then the SIG1 is processed back to the end.

2. Solution

In a registered signal processing function, a loop is used and a waitpid is used in the loop to reclaim the child process resources. As soon as the signal processing function is entered, the signal processing function can reclaim all the resources of the son that has been forked out. Note: The waitpid is to be set to non-blocking mode, otherwise when the loop is entered, it will block in the signal handler function if no child process exits.

3. Wait and Waitpid

wait must be blocking mode . so in the signal processing function, with while1{wait (NULL)} There is a problem, if you enter the signal processing function, as long as the son does not retreat, it will always be blocked here.

The waitpid can be either blocking mode or non-blocking mode.

4. Select and Accept

Both will return-1 when the signal is received.

For signals that the system does not process by default, the program does not receive it, and neither of them will return-1. In other words, SIGCHLD is a signal that the system does not process by default, and if it does not register a signal handler function, select and accept will not return-1 when the child process exits.

Code

Server.c

7#include"my_socket.h"8#include <sys/wait.h>9#include <signal.h>Ten#include <errno.h> One #defineMy_ip "192.168.1.100" A #defineMy_port 8888 - #defineSIZE 192 - #defineMsg_size (SIZE-4) the extern interrno; -typedefstructTag_mag - { -     intMsg_len;//record the true size of the Msg_buf +     CharMsg_buf[msg_size];//the Msg_buf occupies a space of 188byte -}msg, *PMSG; +  A voidMy_handle (intnum) at { -     /*waitpid Parameters: - *-1 means to reclaim every son - * NULL indicates a return value that does not care about the exit of the child process - * Wnohang:wait No hang non-blocking mode - *waitpid return value: in *-1 means no son created - * 0 means no son quits to * Greater than 0 means a son quits +      * */ -      while(Waitpid (-1, NULL, Wnohang) >0) ; the } *  $ intMainintargcChar*argv[])Panax Notoginseng { -     intFd_listen, fd_client; the signal (SIGCHLD, my_handle); +My_socket (&Fd_listen, My_tcp, My_ip, my_port); AMy_listen (Fd_listen,Ten); the  +      while(Fd_client =Accept (Fd_listen, NULL, NULL)) -     { $         /*as long as it is not a signal ignored by the program, accept will receive and return 1*/ $         if(Fd_client = =-1) -         { -             if(errno = =eintr) the             { -                 Continue ;Wuyi}Else  the             { -                  Break;//after the break withdrew, the father retired. The son will be taken over by Init.  Wu             } -}Else  About         { $             if(fork () = =0)//fork son used to communicate with client -             { - MSG recv_msg; -                 intRECVN; A                      while(1 ) +                     { thememset (&recv_msg,0,sizeof(MSG)); -                         /*in my_socket.c, the length to be received by MY_RECV and the length of my_send sent must be an exact value $ * MY_RECV Fill in the length of less than equal to the actual to receive, is possible, greater than the words will never back out of the loop*/ theMy_recv (&AMP;RECVN, fd_client, &recv_msg,4); the                         if(RECVN = =0)//when the opposite client exits (closes the socket), the return value of the system call Recv is 0 the                         { the                              Break ; -}Else in                         { theMy_recv (Null,fd_client, &recv_msg.msg_buf, Recv_msg.msg_len); theMy_send (NULL, fd_client, &recv_msg,4+Recv_msg.msg_len); About  the                         } the                     } the Close (fd_client); +Exit0);  -             } the Close (fd_client);Bayi         } the     } the     return 0 ; -}

Client.c

1#include"my_socket.h"2 #defineMy_ip "192.168.1.100"3 #defineMy_port 66664 #defineSer_ip "192.168.1.100"5 #defineSer_port 88886 #defineSIZE 1927 #defineMsg_size (SIZE-4)8typedefstructTag_mag9 {Ten     intMsg_len; One     CharMsg_buf[msg_size];//188 A}msg, *PMSG; - intMainintargcChar*argv[]) - { the     intsfd; -My_socket (&sfd, my_tcp, My_ip, my_port); - My_connect (SFD, ser_ip, ser_port); - MSG my_msg; +      while(Memset (&my_msg,0,sizeof(MSG)), Fgets (My_msg.msg_buf, msg_size, stdin)! =NULL) -     { +My_msg.msg_len =strlen (MY_MSG.MSG_BUF); AMy_send (NULL, SFD, &my_msg,4+My_msg.msg_len); atmemset (&my_msg,0,sizeof(MSG)); -MY_RECV (NULL, SFD, &my_msg,4); -MY_RECV (NULL, SFD, &my_msg.msg_buf, My_msg.msg_len); -printf"recv from server:%s \ n", my_msg.msg_buf); -      -     } in Close (SFD); -  to}

Note: This code is bound to a port because of client.c, so only one client can be connected, and the reader may enter the port number from the command line or let the system allocate itself.

The drawback of this paradigm is that the server will fork the son for processing each time it receives a client connection request, and fork has time overhead. A better approach is to have the server fork the good son early, the process pool.

Linux client/server programming Paradigm-Apache Server (multi-process)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.