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 paper mainly discusses poll multi-channel i/transfer concurrent 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; "/>
Span style= "text-decoration:none;font-family: ' Microsoft Jas Black ', ' Microsoft Yahei '; font-size:18px;" > multi-process concurrent server multithreaded concurrent server selete Multi-Channel I/O forwarding server This chapter begins with the introduction of poll ( Linux-specific) multi-channel I/O transfer model.
Because multi-process and multithreaded models are relatively simple in implementation, they generally do not use multithreading and multi-process to implement the service model because of their large overhead and CPU height. Select because of its cross-platform, but its maximum limit defaults to 1024, modified to break the 1024 words need to recompile the Linux kernel, poll perfectly solves the limit of 1024.
The main use of the API:
Poll (struct POLLFD *fds, nfds_t nfds, int timeout);
FDS: Passing in an array of outgoing struct bodies
Nfds: Number of struct arrays
Timeout: Listening time
-1 Blocking wait
0 immediately returns without blocking
>0 number of milliseconds to wait
struct pollfd{
int fd; //Listener file descriptor
int events; Listen for event Pollin Listen read Pollout Listen write Pollerr Listen exception
int revents; Events in a listener event that meet the conditions returned
. server[ The following code does not make a mistake, plus the error will cause the code to double, the actual development needs to pay special attention to the return value ]
    
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include < poll.h> #include <sys/socket.h> #include <sys/types.h> #include <arpa/inet.h> #include <string.h> #include <ctype.h> #define &NBSP;CLIENT_MAX&NBSP;1024//define maximum client-side monitoring # define serv_port 9096//Listening Port Int main (int argc, char* argv[]) {int listenfd, Connfd;struct sockaddr_in serv_addr, clie_addr;socklen_t clie_addr_len;struct pollfd event[client_max];int maxi, opt, i, j, nready, n;char buf[bufsiz];// Create a TCP listener Socket Listenfd = socket (af_inet, sock_stream, 0);//Set Port multiplexing opt = 1;setsockopt ( Listenfd, sol_socket, so_reuseaddr, &opt, sizeof (opt));//initialized to 0bzero (&SERV_ADDR, sizeof (SERV_ADDR)) serv_addr.sin_family = af_inet;//set port and convert to network byte order serv_addr.sin_port = htons (Serv_port);/Set native arbitrary ipserv_addr.sin_addr.s_addr = htonl (inaddr_any);//Bind Listenfdbind (listenfd, (struct sockaddr*) &serv_addr, sizeof (SERV_ADDR));//Set simultaneous connection upper limit listen (listenfd, somaxconn);//#define somaxconn 128//connect the listener socket to the event event[0].fd = listenfd;event[0].events = pollin;//initialize the for (i = 1; i < client_max; i++) {event[i].fd = -1;} Maxi = 0;for (;;) {Nready = poll (event, maxi+1, -1);//Client Request connection if (Event[0].revents & pollin) { Clie_addr_len = sizeof (CLIE_ADDR);//Get Connection Connfd = accept (listenfd, (struct sockaddr*) &clie_addr, &clie_addr_len);//Print prompt printf ("%s:%d client connect Successfully!\n ", inet_ntoa (CLIE_ADDR.SIN_ADDR), ntohs (Clie_addr.sin_port));//Add to listen for (i = 1; i < client_max; i++) {if (0&NBSP;>&NBSP;EVENT[I].FD) {event[i].fd = Connfd;break;}} Determine if the listener is full if (ClieNt_max == i) {//Close connection printf ("too many clients!\n"); Close (connfd); continue;} Listener Read Event event[i].events = pollin;if (I > maxi) maxi = i;if (0 == (-- Nready)) continue;} for (i = 1; i <= maxi; i++) {if (0&NBSP;>&NBSP;EVENT[I].FD) continue;//whether there is an event if (Event[i].revents & pollin) {//Empty bzero (buf, sizeof (BUF)); N = read (Event[i].fd, buf, sizeof (BUF));//Whether the other side is closed if (0 == n) {clie_addr_len = sizeof (CLIE_ADDR);//Get Client Information getpeername (event[i].fd, (struct sockaddr*) (&clie_addr, &clie_addr_len);p rintf ("%s:%d client disconnect Successfully!\n ", inet_ntoa (CLIE_ADDR.SIN_ADDR), ntohs (Clie_addr.sin_port));//Closing the Client connection close (Event[i]. FD);//Initialize the event array to -1event[i].fd = -1;} Else if (0 < n) {//Convert to uppercase for (j = 0; j < n; j++) {buf[j] = toupper (Buf[j]);} Writes back to client write (EVENT[I].FD, buf, n);} if (0 == (--nready)) {break;}}}} Close (LISTENFD); return 0;}
This article is from the "Sea" blog, be sure to keep this source http://lisea.blog.51cto.com/5491873/1791967
Linux Network programming-----> High Concurrency--->poll multi-channel I/O transfer server