High-performance network programming-epoll Mechanism

Source: Internet
Author: User

The Select system call not only limits the number of descriptors, but also polls all FD sets even if there is only one active socket in high concurrency, epoll uses the callback event notification mechanism and only needs to process active sockets. For example, the nginx server uses epoll. The following Program (when receiving data larger than 10B) demonstrates the different performance of epoll in edge triggering and level triggering, in edge-trigger mode, our program needs to process this task at one time (for example, to read all the data), because this event will not be added to the kernel event registry next time, on the contrary, level-trigger mode is related to our processing program. If we do not read all the data this time, this task will be registered next time.



# Include <stdio. h> # include <stdlib. h> # include <string. h> # include <sys/types. h> # include <sys/socket. h> # include <netdb. h> # include <unistd. h> # include <fcntl. h> # include <sys/epoll. h> # include <errno. h> # include <libgen. h> # define maxevents 1024 # define buf_size 10 // set this descriptor non blockingstatic int setnonblocking (int sfd) {int flags, s; flags = fcntl (SFD, f_getfl, 0 ); if (flags =-1) {perror ("F Cntl "); Return-1;} flags | = o_nonblock; S = fcntl (SFD, f_setfl, flags); If (S =-1) {perror ("fcntl"); Return-1;} return 0;} // static int create_and_bind (char * port) {struct addrinfo hints; struct addrinfo * result, * RP; int S, SFD; memset (& hints, 0, sizeof (struct addrinfo); hints. ai_family = af_unspec; // IPv4 IPv6 generic hints. ai_socktype = sock_stream;/* we want a TCP socket */hints. ai_flag S = ai_passive; // listening socket; // obtain all available addrinfo S = getaddrinfo (null, port, & hints, & result); If (s! = 0) {fprintf (stderr, "getaddrinfo: % s \ n", gai_strerror (s); Return-1 ;} // use the first ADDR to create socket for (Rp = result; RP! = NULL; RP = RP-> ai_next) {SFD = socket (RP-> ai_family, RP-> ai_socktype, RP-> ai_protocol); If (SFD =-1) continue; S = BIND (SFD, RP-> ai_addr, RP-> ai_addrlen); If (S = 0) {// bind success break;} Close (SFD ); // If bind failed we close this socket} If (Rp = NULL) {fprintf (stderr, "cocould not bind \ n"); Return-1 ;} freeaddrinfo (result); Return SFD;} // Add epollin event of FD to the epollfdvoid addfd (INT epollfd, int FD, int enable_et) {struct epoll_event event; event. data. FD = FD; event. events = epollin; If (enable_et) event. events | = epollet; epoll_ctl (epollfd, epoll_ctl_add, FD, & event); setnonblocking (FD) ;}// the level-trigger logicvoid LT (struct epoll_event * events, int number, int epollfd, int listenfd) {char Buf [buf_size]; int I; for (I = 0; I <number; I ++) {int sockfd = events [I]. data. FD; // new client connection if (sockfd = listenfd) {struct sockaddr_in client_addr; socklen_t Limit = sizeof (client_addr); int connfd = accept (listenfd, (struct sockaddr *) & client_addr, & client_addrlen); If (connfd <0) {perror ("Accept failed .. "); exit (-1);} // register this event addfd (epollfd, connfd, 0);} else if (events [I]. events & epollin) {// If there exists data unreaded, this code will invoke printf ("sockefd % d READ event trigger once \ n", sockfd ); int ret = Recv (sockfd, Buf, buf_size, 0); If (Ret <= 0) {printf ("Some read error or client closed. \ n "); close (sockfd); // will unregister continue;} printf (" Get % d bytes from client: % s \ n ", RET, Buf );} else {// what we are not interested printf ("something else happened \ n") ;}}// the edge-trigger logicvoid et (struct epoll_event * events, int number, int epollfd, int listenfd) {char Buf [buf_size]; int I; for (I = 0; I <number; I ++) {int sockfd = events [I]. data. FD; // new client connection if (sockfd = listenfd) {struct sockaddr_in client_addr; socklen_t Limit = sizeof (client_addr); int connfd = accept (listenfd, (struct sockaddr *) & client_addr, & client_addrlen); If (connfd <0) {perror ("Accept failed .. "); exit (-1);} // register this event and set edge trigger mode addfd (epollfd, connfd, 1);} else if (events [I]. events & epollin) {// In this mode, we shocould read all the data out once printf ("sockefd % d READ event trigger once \ n", sockfd); While (1) {memset (BUF, 0, sizeof (BUF); int ret = Recv (sockfd, Buf, buf_size, 0); If (Ret <0) {// For the nonblocking Io, the following errors indicate the read complete if (errno = eagain | errno = ewouldblock) {printf ("read later \ n "); break;} printf ("Some other error \ n"); close (sockfd); // will unregister break;} else if (ret = 0) {printf ("client closed. \ n "); close (sockfd); break;} else {printf (" Get % d bytes from client: % s \ n ", RET, Buf );}}} else {// what we are not interested printf ("something else happened \ n") ;}} int main (INT argc, char * argv []) {int SFD, s; int EFD; struct epoll_event events [maxevents]; If (argc <2) {fprintf (stderr, "Usage: % s [port] \ n ", basename (argv [0]); exit (exit_failure);} // const char * IP = argv [1]; // int Port = atoi (argv [2]); SFD = create_and_bind (argv [1]); If (SFD =-1) Abort (); // listen for connection coming S = listen (SFD, somaxconn ); if (S =-1) {perror ("listen"); abort () ;}// create a epoll object EFD = epoll_create1 (0 ); if (EFD =-1) {perror ("epoll_create"); abort ();} // Add the listen socket to the event poll addfd (EFD, SFD, 1 ); while (1) {int ret = epoll_wait (EFD, events, maxevents,-1); If (Ret <0) {printf ("epoll wait failture .. \ n "); break;} // et (events, RET, EFD, SFD); LT (events, RET, EFD, SFD);} Close (SFD ); return exit_success ;}


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.