Linux Network programming-----> High Concurrency--->select multi-channel I/O multiplexing server

Source: Internet
Author: User

When doing network service, it is necessary to write concurrent service-side programs. The stability of the front-end client application is partly dependent on the client itself, and more depends on whether the server is fast enough and stable enough.

The common Linux concurrent Server model;


    • Multi-Process Concurrent server

    • Multi-threaded Concurrent server

    • Select multi-channel I/O transfer server

    • Poll Multi-channel I/O forwarding server

    • Epool Multi-Channel I/O forwarding server.


This session focuses on the select multi-channel I/O transfer Server model:

650) this.width=650; "Src=" Http://s4.51cto.com/wyfs02/M00/82/EC/wKioL1dlV3ORUbUGAAISrviO-QM731.png-wh_500x0-wm_3 -wmp_4-s_3902690494.png "title=" concurrency model. png "alt=" wkiol1dlv3orubugaaisrvio-qm731.png-wh_50 "style=" padding:0px; Margin:0px;vertical-align:top;border:none; "/>

The following points are taken into account when using the Select Multi-channel I/O transfer Server model:

1. Select can listen to the number of file descriptors is limited to fd_setsize, generally 1024, simply changing the number of file descriptors opened by the process does not change the number of select listening files

2. It is appropriate to resolve 1024 of the following client requests using SELECT, but if there are too many linked clients, select uses a polling model, which can greatly reduce the server response efficiency and should not devote more effort to the select.

Main API:

int Select (int Nfds, fd_set* Readfds, fd_set* Writefds, fd_set* Execptfds, struct timeval* timmeout);

Nfds: The maximum file description multibyte 1 in the file descriptor set of the monitor, because this parameter tells the kernel the state of how many file descriptors before the cross-test

Readfds: Monitor has read data to reach file descriptor collection, incoming outgoing parameters

Writefds: Monitoring write Data arrives at the file descriptor collection, passing in outgoing parameters

Execptfds: Monitoring exception occurs up to the file descriptor collection, such as out-of-band data arrival exception,

Timeout: Set blocking monitoring time, 3 cases

1. NULL Wait Forever

2. Set Timeval, wait for a fixed time

3. Set the Timeval time to 0, check the description immediately after the return, polling

void Fd_zero (fd_set* set); Initializes the file descriptor set to 0.

void Fd_set (int FD, fd_set* SET); Put the file descriptor in the collection FD position 1

void fd_clr (int FD, fd_set* set); Put the file descriptor in the collection FD position 0

int fd_isset (int FD, fd_set* set); Test file descriptor Set if FD is 1 with return 1, no return 0


Code:

#include  <stdio.h> #include  <stdlib.h> #include  <unistd.h> #include  < arpa/inet.h> #include  <ctype.h> #include  <sys/socket.h> #include  <string.h># Include <sys/types.h> #define &NBSP;SERV_PORT&NBSP;9096//Service occupied Port #define serv_addr  " 10.10.101.105 "//Service occupied Ipint main (int argc, char* argv[]) {INT&NBSP;LISTENFD,&NBSP;CONNFD,  maxfd;struct sockaddr_in serv_addr, clie_addr;socklen_t clie_addr_len;int opt,  i, j, n, nready;char str[INET_ADDRSTRLEN];//INET_ADDRSTRLEN   built-in macros    16char buf[BUFSIZ];//BUFSIZ  built-in macro  8192int client[fd_setsize];//save client Descriptor int maxi;/ /Record client array the largest subscript fd_set rset, allset;//create a listener socket//AF_INET:IPV4//SOCK_STREAMTCP stream type//ipproto_ TCPTCP protocol Listenfd = socket (AF_INET,&NBSP;SOCK_STREAM,&NBSP;IPPROTO_TCP);//Set Port multiplexing opt = 1; SetSockOpt (listenfd, sol_socket, so_reUseaddr, &opt, sizeof (opt));//initialized to 0bzero (&serv_addr, sizeof (SERV_ADDR));//Specify Family:  ipv4serv_addr.sin_family = af_inet;//Specify the port number and convert it to network byte order serv_addr.sin_port = htons (SERV_PORT); /Specify IP and convert to network byte order Inet_pton (AF_INET,&NBSP;SERV_ADDR,&NBSP;&AMP;SERV_ADDR.SIN_ADDR.S_ADDR);//bind to listener socket bind (LISTENFD,   (struct sockaddr*) &serv_addr, sizeof (SERV_ADDR))//Set simultaneous connection request Upper Listen (listenfd,  Somaxconn);//Set all client arrays to -1for (i = 0; i < fd_setsize; i++) {client[i] =  -1;} maxi = -1;//Listener Description Set initialization Fd_zero (&allset);//Add the listener socket to the listener set Fd_set (listenfd, &allset); maxfd  = listenfd;for (;;) {            rset = allset;     nready = select (Maxfd + 1, &rset, null, null, null);     //determine if there is a connection request     if (Fd_isset (Listenfd, &rset)) {Clie_Addr_len = sizeof (CLIE_ADDR);//Get connection Request Connfd = accept (listenfd,  (struct sockaddr* &clie_addr, &clie_addr_len);//Print client Information printf ("%s:%d connect successfully!\n",  inet _ntop (af_inet, &clie_addr.sin_addr.s_addr, str, sizeof (str)),  ntohs (clie_addr.sin_port ));//Add to client collection for (i = 0; i < fd_setsize; i++) {    if (0  > client[i]) {                 client[i] = connfd;    break;}} The client array is full if (fd_setsize == i) {    printf ("Clients at full strength !\n "); continue;;} Add to Listener set Fd_set (connfd, &allset);//Determine if I subscript is greater than maxiif (I > maxi) {    maxi  = i;} Determines whether the new descriptor is greater than MAXFDIF (CONNFD&NBSP;&GT;&NBSP;MAXFD) {    maxfd = connfd;} Determine if there is an event if (0 == (--nready)) {    continue;}} for (i = 0; i <= maxi; i++) {    if (0 > client [i])     continue;if (Fd_isset (client[i], &rset)) {         bzero (buf, sizeof (BUF));     n = read (client[i], buf,  sizeof (BUF));     //when the other side closes     if (0 == n) {     clie_addr_len = sizeof (CLIE_ADDR);     //Get client Information      Getpeername (client[i],  (struct sockaddr*) &clie_addr, &clie_addr_len);     printf ("%s:%d disconnect successfully!\n",  inet_ntop (Af_inet, &clie_addr.sin_ Addr.s_addr, str, sizeof (str)),  ntohs (Clie_addr.sin_port));     //Close connection      close (Client[i])     //remove  &nbsp from the listener;   fd_clr (client[i], &allset);     //client array location restored to -1     client[i] = -1;} Else if (0 < n) {    //all uppercase     for (j = 0;  j < n; j++) {        buf[j] = toupper (Buf[j]);     }    //write-Back to client          write (client[i], buf, n);     }    //determine if there are events      if (0 ==  (--nready)) {                 break;    }}}    }     close (LISTENFD);}





This article is from the "Sea" blog, be sure to keep this source http://lisea.blog.51cto.com/5491873/1791125

Linux Network programming-----> High Concurrency--->select multi-channel I/O multiplexing 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.