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.
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 first few chapters are done .Multi-process Concurrent server, Multi-threaded concurrent Server, Selete Multi-channel I/O forwarding server, poll multiple I/O transfer servers, this chapter begins with the Epoll (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, modify the 1024 words need to recompile the Linux kernel, poll although the limitations of the select1024, but because the poll nature is also a round-robin mechanism, so the increase in the client will also reduce the efficiency . This chapter describes the Epoll multi-channel I/O forwarding server model in detail.
Epoll is an enhanced version of the multiplexed IO interface select/poll for Linux, which significantly increases the CPU utilization of the program in the presence of a small number of active concurrent connections. Because it will reuse the set of file descriptors to pass the result without forcing the developer to prepare the set of file descriptors to be listened to before each wait for the event, another point is that it does not need to traverse the entire set of descriptors that are being listened to when the event is acquired. Just walk through the set of descriptors that are joined to the ready queue by a kernel IO event that wakes up asynchronously.
Currently, Epell is a popular preferred model in Linux large scale concurrent network programs.
Epoll provides edge triggering (edge triggered) in addition to the level triggered of Select/poll IO events, which makes it possible for user space programs to cache IO status and reduce epoll_wait/ Epoll_pwait calls to improve application efficiency.
The main API used:
int epoll_create (int size);
Summary: Create a epoll handle
Parameters: Number of listeners
int epoll_ctl (int epfd, int op, int fd, struct epoll_event* evvent);
Simple: Control an event on a Epoll listener's file descriptor, register, modify, delete
EPFD: Handle for Epoll_create
OP: Action, represented by 3 macros
Epoll_ctl_add Register for new FD to EPFD
Epoll_ctl_mod modifying a monitored event for an already registered FD
Epoll_ctl_del Delete an FD from EPFD
Event: Tells the kernel what to listen for
struct epoll_event{
__uint32_t events; /*epoll events*/
epoll_data_t data; /"Use data variable"/
}
typedef Union epoll_data{
void* ptr;
int FD;
uint32_t u32;
uint64_t U64;
}epoll_data_t;
Epollin listen for read events, Epollout listen for write events Epollerr listen for exception events
int epoll_wait (int epfd, struct epoll_event* events, int maxevents, int timeout);
Function Description: Waits for the event to be generated on the monitored file descriptor.
EPFD: Handle for Epoll_create
Events: A collection of events that are used to store the kernel
Maxevents: Tell the kernel how big this events is, the value of this maxevents cannot be greater than the size of the creation epoll_create ()
Timeout: Wait time
-1: Blocking wait
0: Immediate return, non-blocking
>0: Specify milliseconds
Return value: Successful return of how many file descriptors are ready, time to return 0, error returned-1
The code is as follows:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys /types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <string.h># include <sys/epoll.h> #include <ctype.h> #define &NBSP;SERV_PORT&NBSP;9096//Service Port # define client_max 1024//Client Max Connection Int main (int argc, char* argv[]) {INT&NBSP;LISTENFD, connfd, efd;struct sockaddr_in serv_addr, clie_addr;socklen_t clie_addr_len; Char buf[bufsiz];int n, i, j, nready, opt;struct epoll_event op[client _max+1], ep;//Create a listener socket Listenfd = socket (AF_INET,&NBSP;SOCK_STREAM,&NBSP;IPPROTO_TCP);//set Port multiplexing opt = 1;setsockopt (listenfd, sol_socket, so_reuseaddr, &opt, sizeof (opt));// Bind address Family bzero (&serv_addr, sizeof (SERV_ADDR)); Serv_addr.sin_family = af_inet;serv_addr.sin_port = htons (serv_PORT); serv_addr.sin_addr.s_addr = htonl (Inaddr_any); Bind (listenfd, (struct sockaddr*) & Serv_addr, sizeof (SERV_ADDR));//Set connection up to maximum listen (listenfd, somaxconn);//Create Epollefd = epoll _create (client_max+1);//Add Request Connection Listener socket Ep.events = epollin;ep.data.fd = listenfd;epoll_ctl (EFD , &NBSP;EPOLL_CTL_ADD,&NBSP;LISTENFD,&NBSP;&EP); for (;;) {//Listener event nready = epoll_wait (efd, op, client_max + 1, -1); for (i = 0 ; i < nready; i++) {if (!) ( Op[i].events & epollin)) continue;//when there is a connection request if (OP[I].DATA.FD&NBSP;==&NBSP;LISTENFD) {Clie_addr_len = sizeof (CLIE_ADDR);//Get Connection Connfd = accept (listenfd, (struct sockaddr*) &clie _addr, &clie_addr_len);p rintf ("%s:%d connect successfully!\n", inet_ntoa (Clie_addr.sin _ADDR), ntohs (Clie_addr.sin_port));//listener Read Event ep.events = epollin;ep.data.fd = connfd;// Add to monitor Epoll_ctl (EFD, &NBSP;EPOLL_CTL_ADD,&NBSP;CONNFD,&NBSP;&EP);} else{//Room-End Message bzero (buf, sizeof (BUF)); N = read (Op[i].data.fd, buf, sizeof (BUF));// The client closes the connection if (0 == n) { //removes epoll_ctl from the listener (efd, EPOLL_ Ctl_del, op[i].data.fd, null); //close connection close (Op[i]. DATA.FD);} else{//to uppercase for (j = 0; j < n; j++) {buf[j] = toupper (buf[j]);} Write back to the client (op[i].data.fd, buf, n);}}} Close (LISTENFD); close (EFD); return 0;}
This article is from the "Sea" blog, be sure to keep this source http://lisea.blog.51cto.com/5491873/1792743
Linux Network programming-----> High Concurrency--->epoll multi-channel I/O transfer server