Socket programming Practices (6)--TCP service-side considerations

Source: Internet
Author: User

Zombie Process Processing

1) Avoid the zombie process by ignoring the SIGCHLD signal

Adding in server-side code

Signal (SIGCHLD, sig_ign);

2) solve the zombie process through the Wait/waitpid method

Signal (sigchld,onsignalcatch); void Onsignalcatch (int signalnumber) {    wait (NULL);}

3) If multiple clients are closed at the same time, the problem description is shown in the following two images:


/** client-side implementation of the test Code **/int main () {    int sockfd[50];    for (int i = 0; i < ++i)    {        if (sockfd[i] = socket (af_inet, sock_stream, 0)) = =-1)            err_exit ("Socket ER Ror ");        struct sockaddr_in serveraddr;        serveraddr.sin_family = af_inet;        Serveraddr.sin_port = htons (8001);        SERVERADDR.SIN_ADDR.S_ADDR = inet_addr ("127.0.0.1");        if (Connect (sockfd[i), (const struct sockaddr *) &serveraddr, sizeof (serveraddr)) = =-1)            err_exit ("Connect Error ");    }    Sleep (20);}

By pressing CTRL + C while the client is running, you can see that the number of zombie processes that are generated when the server side starts 50 sub-processes and all of the clients are disconnected together is amazing (and this proves that the SIGCHLD signal is unreliable)!


Workaround-Transform the server-side signal capture function as follows:

void Sighandler (int signo) {while    (Waitpid ( -1, NULL, Wnohang) > 0)        ;}

Waitpid return value Explanation:

On success, returns the process ID of the "the child" whose state has changed (return has ended running

PID of the child process); If Wnohang is specified and one or more child (ren) specified by PID exist,

but the yet changed state and then 0 are returned ( if there are still many sub-processes identified by the PID parameter , and

And there is no sign of ending, return 0). On error,-1 is returned.

Address Query API
#include <sys/socket.h>int getsockname (int sockfd, struct sockaddr *addr, socklen_t *addrlen);//get local addr struct int Getpeername (int sockfd, struct sockaddr *addr, socklen_t *addrlen);//Get the other addr structure int gethostname (char *name, size_t len); int sethostname (const char *name, size_t len), #include <netdb.h>extern int h_errno;struct hostent *gethostbyname ( const char *name); #include <sys/socket.h>       /* for af_inet */struct hostent *gethostbyaddr (const void *ADDR, sock len_t len, int type), struct hostent *gethostent (void);

/** get the native IP list **/int gethostip (char *ip) {    struct hostent *hp = gethostent ();    if (HP = = NULL)        return-1;    strcpy (IP, inet_ntoa (* (struct in_addr*) hp->h_addr));    return 0;} int main () {    char host[128] = {0};    if (gethostname (host) = =-1)        err_exit ("GetHostName error");    cout << "Host-name:" << host << Endl;    struct Hostent *hp = gethostbyname (host);    if (HP = = NULL)        err_exit ("gethostbyname error");    cout << "IP list:" << Endl;    for (int i = 0; Hp->h_addr_list[i]! = NULL; ++i)    {        cout << ' \ t '             << inet_ntoa (* (struct IN_ADD r*) hp->h_addr_list[i]) << Endl;    }    Char ip[33] = {0};    Gethostip (IP);    cout << "LOCAL-IP:" << IP << Endl;}

11 States of the TCP protocol

1. (both client and server are in this machine: Both sides (child process of server, with client) Link has been established (established), waiting for communication)

2. One end of the first close will enter the TIME_WAIT state; One end of the passive shutdown can enter the Close_wait state (the server side is first closed)

3.time_wait time is 2MSL (twice times the maximum lifetime of the message)

Reason: (ACK y+1) if the sending failure can be re-sent, so if the server side does not set the address reuse, the server in a short period of time will not be restarted;

The server side is in closed state, not equal to the client is also in the closed state.

(, client first close, client appears time_wait state)

The 1th state of the 4.TCP/IP protocol: There are only 10 states on the graph and a CLOSING state

Causes of closing status:

The server side shuts down simultaneously with the client side (while calling Close, at which point both ends send fin packets to the peer), the closing state is generated, and both sides enter the TIME_WAIT state (for example).


Sigpipe Signal

It is permissible to write to a socket that has received fin, and to receive fin just means that the other party no longer sends the data, but after receiving the RST segment, if you continue to write, the call to write will produce a sigpipe signal, which we usually ignore for processing this signal.

Signal (sigpipe, sig_ign);

/** test: Send each message in the client sends two times when the server side shuts down, the server sends a FIN section to the client, and after the first message is sent, the server sends an RST section to the client side, and the second message is sent ( The sigpipe signal is generated when the write is called; Note: the client-side test code uses the socket library **/void sighandler (int signo) {    if (sigpipe = = Signo) that will be introduced in the next section    {        cout << "Receive sigpipe =" << sigpipe << Endl;        Exit (exit_failure);}    } int main () {    signal (sigpipe, sighandler);    TCPClient Client (8001, "127.0.0.1");    Try    {        std::string msg;        while (Getline (CIN, msg))        {            client.send (msg);            Client.send (msg);   Second time send            msg.clear ();            Client.receive (msg);            Client.receive (msg);            cout << msg << Endl;            Msg.clear ();        }    }    catch (const socketexception &e)    {        cerr << e.what () << Endl;    }}

the difference between close and shutdown
#include <unistd.h>int close (int fd), #include <sys/socket.h>int shutdown (int sockfd, int);

shutdown

shut_ RD

shut_wr

Close the write end

shut_rdwr

Read and write closed

1.close terminated the data transfer. two x direction ;

The shutdown can have the option of terminating data transfer in a direction or terminating data transmission in two directions.

2.shutdown HOW=SHUT_WR (Turn off the write end) guarantees that the peer receives an EOF character (Fin segment), regardless of whether another process has already opened the socket (shutdown does not take a reference count).

and close needs to wait for the socket reference count to be reduced to 0 o'clock to send the fin segment . That is, until all processes have closed the socket.

Sample Analysis:

The client sends the server in sequence: Fin E D C B A, if fin is called close before the client has received ABCDE, then client side will never receive ABCDE, and through the shutdown function, You can choose to close only the sender of the client without shutting down the receiving end, the client side can also receive ABCDE information;


/** Test: Implement the code similar to the above (using Close/shutdown) two ways to implement **/

For full source code, please refer to:

http://download.csdn.net/detail/hanqing280441589/8486517

Note: The best reader needs to have the base of select and readers without select basics can refer to my blog <socket Programming Practices (8) > Related sections

Socket programming Practices (6)--TCP service-side considerations

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.