Socket Programming Practice (4)--Multi-process concurrent server

Source: Internet
Author: User
Tags socket error stdin htons

1.Socket Address multiplexing

int getsockopt (int sockfd, int level, int optname,               void *optval, socklen_t *optlen); int setsockopt (int sockfd, int lev El, int optname,               const void *optval, socklen_t optlen);

The server uses so_reuseaddr whenever possible, calling setsockopt to set so_reuseaddr socket options before binding. This option allows the server to restart the servers without waiting for the time_wait state to disappear (the Time_wait status is described later).

You can add code before bind (complete code, please refer to the end of the blog post):

    int on = 1;    if (setsockopt (listenfd,sol_socket,so_reuseaddr,                   &on,sizeof (on)) = =-1)        err_exit ("SetSockOpt so_ REUSEADDR error ");

Used to support address reuse.

2.process-per-connecton

The biggest drawback of our echo server is the inability to support a multi-client connection, even if the client is able to connect to the server (there is no error returning when clients are connected).   Server does not serve the customer, (direct no response), although the link is there (that is, the client is already connected to the server, but the server is not responding to you ...),  Our proposed improvement is process-per-connection (a link to a process,  we have proposed in the multi-threaded chapter a connection to a thread,  this scenario can have a higher concurrency than many processes in comparison);

/** Example: Echo server improvements, multi-process model (client not changed) **/void echo (int clientfd); int main () {int LISTENFD = socket (Af_inet, Sock_strea    M, 0);    if (LISTENFD = =-1) err_exit ("Socket error");    int on = 1; if (setsockopt (Listenfd,sol_socket,so_reuseaddr, &on,sizeof (on)) = =-1) err_exit ("setsockopt    SO_REUSEADDR error ");    struct sockaddr_in addr;    addr.sin_family = af_inet;    Addr.sin_port = htons (8001);    ADDR.SIN_ADDR.S_ADDR = htonl (Inaddr_any);    if (Bind (LISTENFD, (const struct sockaddr *) &addr, sizeof (addr)) = =-1) err_exit ("Bind error");    if (Listen (LISTENFD, somaxconn) = =-1) err_exit ("Listen error");    struct sockaddr_in clientaddr;    Remember: Be sure to initialize socklen_t Addrlen = sizeof (CLIENTADDR) here;        while (true) {int clientfd = accept (LISTENFD, (struct sockaddr *) &clientaddr, &addrlen);        if (clientfd = =-1) err_exit ("Accept error"); Print client IP address and port number cout << "Client information: "<< Inet_ntoa (clientaddr.sin_addr) <<", "<< Ntohs (clientaddr.sin_port) << Endl;        pid_t pid = fork ();        if (PID = =-1) err_exit ("fork Error");        else if (PID > 0) Close (CLIENTFD);            The child process processes the link else if (pid = = 0) {close (LISTENFD);            Echo (CLIENTFD);        Sub-process must exit, otherwise, the child process will return to accept the exit (exit_success); }} close (LISTENFD);}    void echo (int clientfd) {char buf[512] = {0};    int readbytes;        while (readbytes = Read (CLIENTFD, buf, sizeof (BUF))) > 0) {cout << buf;        if (Write (CLIENTFD, buf, readbytes) = =-1) err_exit ("Write socket error");    memset (buf, 0, sizeof (BUF));        } if (readbytes = = 0) {cerr << "client connect closed ..." << Endl;    Close (CLIENTFD); } else if (readbytes = =-1) err_exit ("Read socket error");}

Complete code implementation:

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

3. The design and implementation of peer chat

Server side and client have two processes:

(1) The parent process is responsible for reading data from the socket and writing it to the terminal, because the parent process uses a blocking version of the read system call, so if there is no data in the socket, the parent process will always block; If read returns 0, indicating that the peer connection is closed, the parent process sends a SIGUSR1 signal to the child process to notify it to exit;

(2) The child process is responsible for reading data from the keyboard to write it to the socket, if the keyboard has no data, then the fgets call will be blocked;

Serever-side code with description int main () {int LISTENFD = socket (af_inet, sock_stream, 0);    if (LISTENFD = =-1) err_exit ("Socket error");    int on = 1; if (setsockopt (Listenfd,sol_socket,so_reuseaddr, &on,sizeof (on)) = =-1) err_exit ("setsockopt    SO_REUSEADDR error ");    struct sockaddr_in addr;    addr.sin_family = af_inet;    Addr.sin_port = htons (8001);    ADDR.SIN_ADDR.S_ADDR = htonl (Inaddr_any);    if (Bind (LISTENFD, (const struct sockaddr *) &addr, sizeof (addr)) = =-1) err_exit ("Bind error");    if (Listen (LISTENFD, somaxconn) = =-1) err_exit ("Listen error");    struct sockaddr_in clientaddr;    socklen_t Addrlen = sizeof (CLIENTADDR);    int clientfd = Accept (LISTENFD, (struct sockaddr *) &clientaddr, &addrlen);    if (clientfd = =-1) err_exit ("Accept error");    Close (LISTENFD); Print client IP address and port number cout << "Client information:" << Inet_ntoa (clientaddr.sin_addr) << "," <& Lt Ntohs (clientaddr. sin_port) << Endl;    Char buf[512] = {0};    pid_t pid = fork ();    if (PID = =-1) err_exit ("fork Error");        Parent process: Socket--terminal else if (PID > 0) {int readbytes;            while (readbytes = Read (CLIENTFD, buf, sizeof (BUF))) > 0) {cout << buf;        memset (buf, 0, sizeof (BUF));        } if (readbytes = = 0) cout << "Client connect closed...\nserver exiting ..." << Endl;        else if (readbytes = =-1) err_exit ("Read socket error");    Notifies the child process to exit Kill (PID, SIGUSR1);        }//Sub-process: keyboard, Socket else if (PID = = 0) {signal (SIGUSR1, Sighandler);                while (Fgets (buf, sizeof (BUF), stdin)! = NULL) {if (write (CLIENTFD, buf, strlen (buf)) = = =-1)            Err_exit ("Write socket error");        memset (buf, 0, sizeof (BUF));    }} close (CLIENTFD); Exit (exit_success);}
Client-side code and description int main () {int SOCKFD = socket (af_inet, sock_stream, 0);    if (SOCKFD = =-1) err_exit ("Socket error");    Fill in the server port number and IP address 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, (const struct sockaddr *) &serveraddr, sizeof (serveraddr)) = =-1) err_exit ("Connect error");    Char buf[512] = {0};    pid_t pid = fork ();    if (PID = =-1) err_exit ("fork Error");        Parent process: Socket--terminal else if (PID > 0) {int readbytes;            while (readbytes = Read (SOCKFD, buf, sizeof (BUF))) > 0) {cout << buf;        memset (buf, 0, sizeof (BUF));        } if (readbytes = = 0) cout << "Server connect closed...\nclient exiting ..." << Endl;        else if (readbytes = =-1) err_exit ("Read socket error");    Kill (PID, SIGUSR1); }//Child process: keyboard, Socket else if (PID = = 0) {signal (SIGUSR1, Sighandler);                while (Fgets (buf, sizeof (BUF), stdin)! = NULL) {if (write (SOCKFD, buf, strlen (buf)) = = =-1)            Err_exit ("Write socket error");        memset (buf, 0, sizeof (BUF));    }} close (SOCKFD); Exit (exit_success);}

Complete code implementation:

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

Socket Programming Practice (4)--Multi-process concurrent server

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.