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;&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;>&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   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