Non-blocking sockets and Epoll

Source: Internet
Author: User

block the socket. – A blocking call means that the current thread is suspended until the call results are returned.  Functions are returned only after the result is obtained.  – The Read,fread function call will block the thread for the file operation.  – For Socket,accept and recv, the Recvfrom function call will block the thread.  – In blocking mode, multithreading is often required to prevent the entire process from being blocked and suspended. – The total number of threads that can be concurrent in a process is limited, and processing a large number of client sokcet connections (such as tens of thousands of clients) is not convenient and inefficient by threading the socket concurrently. non-blocking sockets. – A non-blocking call means that the call returns immediately.  – In nonblocking mode, the Accept and recv, Recvfrom function calls return immediately.  – The Accept function is called in the nonblocking state, and if there is no client socket connection request, then the Accept function returns-1, while the errno value is 11. – The recv, Recvfrom function is called in the nonblocking state, and if there is no data, the function returns-1, while the errno value is 11.  If the socket is closed, the function returns 0. – Calling the Send function on a closed socket in the nonblocking state will trigger a sigpipe signal that the process must capture because the Sigpipe system defaults to the shutdown process. fcntl function CallThe FCNTL function can set a file or a socket descriptor as either a blocking or nonblocking state int fcntl (int fd, int cmd, ...//ARG/), the parameter fd is the file descriptor or socket to be set. Parameter cmd, F_GETFL to get the current state, F_SETFL for the set state. The macro definition O_nonblock represents non-blocking, and 0 represents blocking. The return value is the current state of the descriptor.
 int  opts = Fcntl (St, F_GETFL);  if  (OPTs < 0    " fcntl failed%s\n  "  , strerror (errno));} OPTs  = opts |  O_nonblock;  if  (Fcntl (St, F_SETFL, opts) < 0  ) {printf (   fcntl failed%s\n   "  
fcntl Function Call Set block example if 0 0 {    printf ("fcntl failed%s\n", Strerror (errno));}

in non-blocking mode, how can I know if the accept and recv have data return? Epoll is an improved poll of the Linux kernel for processing large-volume file descriptors, an enhanced version of the multiplexed IO interface select/poll under Linux, which significantly increases the CPU utilization of the program in cases where there are only a few active instances of a large number of concurrent connections. Epoll system call Function:–epoll_create epoll_create is used to create a Epoll file descriptor.  –epoll_ctl Epoll_ctl is used to add/modify/delete file descriptors and their events that need to be listened to. –epoll_wait.  The epoll_wait receives an IO event of interest to the user that occurs on the descriptor being listened to.  After the –epoll file descriptor is exhausted, you need to close it with close. – Every time you add/modify/delete a file descriptor you need to call Epoll_ctl, so try to call Epoll_ctl as few as possible. epoll_create:–int epoll_create (int size);  –epoll_create creates a handle to the epoll.  – The parameter size specifies the maximum number of handles supported by Epoll.  – The function returns a new Epoll handle, and all subsequent operations are handled through the handle. – After the handle is exhausted, close () is required to dismiss the created epoll handle. Uepoll_ctl:–int epoll_ctl (int epfd, int op, int fd, struct epoll_event *event);  – The parameter EPFD is the return value of Epoll_create (). – The parameter op represents an action, represented by three macros: epoll_ctl_add: Registering a new FD to EPFD; epoll_ctl_mod: Modifying a listener event for an already registered FD; epoll_ctl_del: Deleting a EPFD from fd;–  The parameter FD is the socket descriptor that needs to be monitored. – The parameter event notifies the kernel what event to listen on.
struct The epoll_event structure is as follows: TypeDef    Union epoll_data {void *ptr;     int FD;    __uint32_t u32;    __uint64_t U64;} epoll_data_t; struct epoll_event {    /* *    /  * */ };
Events Definition:–epollin: Indicates that the corresponding file descriptor can be read (including the opposite end of the socket gracefully closed); –epollout: Indicates that the corresponding file descriptor can be written; –epollpri: indicates that the corresponding file descriptor has an urgent data readable (this should indicate that there is an out-of-band data coming); Epollerr: Indicates an error occurred with the corresponding file descriptor; –epollhup: Indicates that the corresponding file descriptor is hung up; –epollet: Sets the Epoll to edge trigger (edge triggered) mode, which is relative to the horizontal trigger (level triggered); –epolloneshot: Listen to only one event, and if you need to continue listening to the socket after listening to this event, you need to add the socket to the Epoll queue again. about the ET, lt two Modes of operation:The LT (level triggered) is the default mode of operation and supports both block and No-block sockets.  – In the LT mode, the kernel notifies a file descriptor that it is ready, and can then perform IO operations on the Ready FD. – If you don't do anything, the kernel will continue to notify you, so it's a little less likely to program errors. ET (edge-triggered) is a high-speed mode of operation and supports only no-block sockets. – In et mode, the kernel tells you through Epoll when the descriptor is never ready to be ready.  The –et mode assumes that you know that the file descriptor is ready and no more ready notifications are sent for that file descriptor until you do something that causes the file descriptor to no longer be ready. – The kernel does not send more notifications if the FD is not being IO-made again (causing it to become not ready again).  ET and LT difference: –lt event will not be discarded, but as long as the read buffer inside the data can let the user read, then constantly notify you. –et is only notified at the time the event occurs.  It is simple to understand that LT is a horizontal trigger, and ET is an edge trigger. The –LT mode is triggered whenever an event is unhandled, and ET is triggered only when the high-low level transforms (that is, the state is 1 to 0 or 0 to 1).

epoll_wait:–int epoll_wait (int epfd, struct epoll_event *events, int maxevents, int timeout);  – The parameter EPFD is the return value of Epoll_create ().  – Parameter events is a epoll_event* pointer, and when epoll_wait this function succeeds, the epoll_events will store all read and write events.  – The parameter maxevents is the number of all socket handles currently required to be monitored.  – The parameter timeout is the timeout for epoll_wait, which is 0 when it returns immediately, and 1 is the time to wait until there is an event range, a positive integer representing such a long time. – Generally, if the network main loop is a separate thread, it can be used-one for the other, which guarantees some efficiency, and if it is the same thread as the main logic, it can be used to guarantee the efficiency of the main loop. The epoll_wait range should be followed by a loop that iterates through all the events. Epoll Example
/** * Created on:2013 December 27 * author:zhujy*/#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<fcntl.h>#include<errno.h>#include<string.h>#include<sys/socket.h>#include<sys/types.h>#include<sys/epoll.h>#include<netinet/inch.h>#include<arpa/inet.h>ssize_t Socket_recv (intSt) {    Charbuf[1024x768]; memset (BUF,0,sizeof(BUF)); ssize_t RC= Recv (St, buf,sizeof(BUF),0); if(RC <=0) {printf ("recv failed%s\n", Strerror (errno)); } Else{printf ("recv%s\n", BUF); Send (St, buf, RC,0); }    returnRC;}intSocket_accept (intListen_st) {    structsockaddr_in client_addr; socklen_t Len=sizeof(CLIENT_ADDR); memset (&AMP;CLIENT_ADDR,0,sizeof(CLIENT_ADDR)); intClient_st = Accept (Listen_st, (structSOCKADDR *) &client_addr, &Len); if(Client_st <0) printf ("Accept failed%s\n", Strerror (errno)); Elseprintf ("Accept by%s\n", Inet_ntoa (CLIENT_ADDR.SIN_ADDR)); returnClient_st;}voidSetnonblocking (intSt//set socket to non-blocking{    intopts =Fcntl (St, F_GETFL); if(OPTs <0) {printf ("Fcntl failed%s\n", Strerror (errno)); } opts= OPTs |O_nonblock; if(Fcntl (St, F_SETFL, opts) <0) {printf ("Fcntl failed%s\n", Strerror (errno)); }}intSocket_create (intPort) {    intST = socket (af_inet, Sock_stream,0); intOn =1; if(SetSockOpt (St, Sol_socket, SO_REUSEADDR, &on,sizeof(ON)) == -1) {printf ("setsockopt failed%s\n", Strerror (errno)); return 0; }    structsockaddr_in addr; memset (&AMP;ADDR,0,sizeof(addr)); Addr.sin_family=af_inet; Addr.sin_port=htons (port); Addr.sin_addr.s_addr=htonl (Inaddr_any); if(Bind (St, (structSOCKADDR *) &addr,sizeof(addr)) == -1) {printf ("bind port%d failed%s\n", Port, Strerror (errno)); return 0; }    if(Listen (St, -) == -1) {printf ("Listen failed%s\n", Strerror (errno)); return 0; }    returnSt;}intMainintArgChar*args[]) {    if(Arg <2)        return-1; intIport = Atoi (args[1]); intListen_st =socket_create (Iport); if(Listen_st = =0)        return-1; structEpoll_event EV, events[ -];//declare variables for epoll_event struct, Ev for registering events, arrays for returning events to be processed    intEPFD = Epoll_create ( -);//generates a epoll dedicated file descriptor for handling the AcceptSetnonblocking (Listen_st);//set socket to non-blocking modeEV.DATA.FD = Listen_st;//set the file descriptor associated with the event to be processedev.events = Epollin | Epollerr | Epollhup;//set the type of event to be processedEpoll_ctl (EPFD, Epoll_ctl_add, Listen_st, &ev);//Registering Epoll Events    intSt =0;  while(1)    {        intNfds = epoll_wait (EPFD, events, -, -1);//waiting for the Epoll event to occur        if(Nfds = =-1) {printf ("epoll_wait failed%s\n", Strerror (errno));  Break; }        inti;  for(i =0; i < Nfds; i++)        {            if(Events[i].data.fd <0)                Continue; if(EVENTS[I].DATA.FD = = Listen_st)//a socket user is monitored to connect to the bound socket port to establish a new connection. {St=socket_accept (Listen_st); if(St >=0) {setnonblocking (ST); EV.DATA.FD=St; Ev.events= Epollin | Epollerr | Epollhup;//set the type of event to be processedEpoll_ctl (EPFD, Epoll_ctl_add, St, &ev); Continue; }            }            if(Events[i].events & Epollin)//socket receives data{St=EVENTS[I].DATA.FD; if(Socket_recv (ST) <=0) {Close (ST); EVENTS[I].DATA.FD= -1; }            }            if(Events[i].events & Epollerr)//Socket Error{Close (ST); EVENTS[I].DATA.FD= -1; }                        if(Events[i].events & Epollhup)//Socket Error{Close (ST); EVENTS[I].DATA.FD= -1;    }}} close (EPFD); return 0;}

Copy to Google TranslateTranslation Results

Non-blocking sockets and Epoll

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.