Network HTTP Server-v2-epoll version

Source: Internet
Author: User
Tags epoll sendfile sprintf strcmp htons

Epoll basic interface with the process of establishing a TCP connection view:

Network uses Epoll to implement a TCP server-a novice bird-51CTO Tech Blog

http://shaungqiran.blog.51cto.com/10532904/1784410


Focus:

< Span style= "font-family: ' Microsoft Jas Black ', ' Microsoft Yahei '; Font-size:20px;color:rgb (255,0,0);" >        epoll followed by multiplexed I/O model . . So we have to choose the right time to read   or write. For the kernel, to a socket file descriptor The listener of the read and write events is a separate (readable, not necessarily writable). Therefore, to achieve the highest efficiency. The user-made I/O operation should also read, write separate.

In the case of read-write separation, the server-side service is sometimes required for client-submitted information for HTTP servers. Read and write separations can cause an inability to respond effectively. So we have to maintain a buffer for ourselves, to spring up the valid contents of each socket FD. Until the write event is used, and then the memory is reclaimed.

Each event handle has a not-long-used pointer (void*). Just so we can use it to point to our buffers,

typedef Union EPOLL_DATA {

void *ptr; Our available ptr is used to store a pointer to the buffer

int FD;

__uint32_t u32;

__uint64_t U64;

} epoll_data_t;

Events of interest and events that are triggered

struct Epoll_event {

__uint32_t events; /* Epoll Events */

epoll_data_t data; /* USER Data variable */

};

Epoll.c

#include   "httpd.h" #include  <sys/epoll.h> #include  <malloc.h> #include  < netdb.h> #include  <sys/utsname.h> #include  <net/if.h> #include  <sys/ioctl.h># define _maxfd_ 10  #define  errorip -1int set_non_block (INT&NBSP;FD) {Int old_ Flag=fcntl (FD,F_GETFL); if (old_flag<0) {perror ("fcntl");//exit ( -4); return -1;} if (Fcntl (fd,f_setfl,old_flag| O_nonblock) <0) {perror ("fcntl"); return -1;} return 0;} Int startup (Char* ip,int port) {int sock=socket (af_inet,sock_stream,0); struct sockaddr _IN&NBSP;SERVER;SERVER.SIN_FAMILY=AF_INET;SERVER.SIN_ADDR.S_ADDR=INET_ADDR (IP); server.sin_port=htons (port); int  flag=0;//printf ("port  %d  %d", Port, (htons (port))), if (Bind (sock, struct  sockaddr *) &server,sizeof (server)) <0) {perror ("bind"); exit (-2);} if ( setsockopt (sock, sol_socket, so_reuseaddr, &flag, sizeof (flag))  == -1)       {      perror ("setsockopt");       exit (1);       }  if (Listen (sock,50 ) {<0) {perror ("listen"); exit (-3);} Return sock;} Void usage (Char* arg) {printf ("usage %s [ip] [port]\n", Arg);} Void epollup (int sock) {int epoll_fd=epoll_create); if (epoll_fd<0) {perror ("Epoll"); return;} int timeout_num=0;int done=0;int timeout=10000;int i=0;int ret_num=-1;struct  epoll_event ev;struct epoll_event event[100];ev.data.fd=sock;ev.events=epollin| epollet;//fd_num=1;//printf ("listen sock%d\n", sock); if (Epoll_ctl (Epoll_fd,epoll_ctl_add,sock,&ev) < 0) {perror ("Epoll_ctl"); return ;} while (!done) {switch (ret_num=epoll_wait (epoll_fd,event,256,timeout)) {case -1:{perror ("epoll_wait"); Case 0 :{if (timeout_num++>20) done=1;printf ("time out...\n"); break;} Default:{for (i=0;i<ret_num;++i) {if (Event[i].data.fd==sock&&event[i].events&epollin) {int  new_sock=-1;struct sockaddr_in client;socklen_t len=sizeof (client); while (New_sock=accept (sock, (struct sockaddr*) &client,&len)) {if (new_sock<0) {//perror ("accept"); if (Set_non_block (new_sock) <0) {echo_error (new_sock,500); continue;} printf (" epoll :%d\n", new_sock); ev.data.fd=new_sock;ev.events=epollin| Epollet;if (Epoll_ctl (Epoll_fd,epoll_ctl_add,new_sock,&ev) <0) {perror ("Epoll_ctl"); Echo_error (New_sock, 503); continue;}} break;} Else {if (Event[i].events&epollin) {int fd=event[i].data.fd;pev_buf pev= (pev_buf) malloc ( sizeof (EV_BUF)); Event[i].data.ptr=pev;pev->fd=fd;if (Epoll_recv_http (&event[i]) <0) {free (PEV); if (epoll _ctl (Epoll_fd,epoll_ctl_del,fd,&ev) <0) perror ("Read epoll_ctl_del"); Close (FD); continue;} Elseevent[i].events=epollout;} if (event[i].events&epollout) {int fd= ((pev_buf) (EveNT[I].DATA.PTR)->fd;epoll_echo_http (event+i), if (Epoll_ctl (Epoll_fd,epoll_ctl_del,fd,&ev) <0) perror (" Out_ctl_del ") Free ((PEV_BUF) event[i].data.ptr);p rintf (" epoll close :%d\n ", FD); close (FD);}} Break;}}}} Int main (int argc,char* argv[]) {if (argc!=3) {usage (argv[0]); exit (-1);} Int port=atoi (argv[2]); Int listen_sock;char* ip=null;if (strcmp (argv[1], "any") ==0) {INT&NBSP;SFD,  intr;struct ifreq buf[16];    struct ifconf ifc;     sfd = socket  (af_inet, sock_dgram, 0);      if   (sfd < 0) return errorip;ifc.ifc_len = sizeof (BUF);ifc.ifc_buf =  ( caddr_t) buf;if  (IOCTL (sfd, siocgifconf,  (char *) &ifc)) return errorip;intr =  ifc.ifc_len / sizeof (struct ifreq);while  (intr-- > 0 &&  ioctl (sfd, siocgifaddr,  (CHAR&Nbsp;*) &buf[intr]); close (SFD); Ip= inet_ntoa (((struct sockaddr_in*) (&AMP;BUF[INTR].IFR_ADDR))- &GT;&NBSP;SIN_ADDR);p rintf ("%s\n", IP); listen_sock=startup (Ip,port);} Else listen_sock=startup ( argv[1],port);//printf ("port %s %d", Argv[2],port);     set_non_block (Listen_sock); Epollup (Listen_sock); close (listen_sock); return 0;}

  httpd.h

#ifndef  __MYHTTP__#define __MYHTTP__#include <stdio.h> #include  <netinet/in.h># include <arpa/inet.h> #include  <sys/types.h> #include  <sys/socket.h> #include  <unistd.h> #include  <string.h> #include  <stdlib.h> #include  <errno.h > #include  <fcntl.h> #include  <sys/stat.h> #include  <sys/epoll.h> #include  <sys/sendfile.h> #define &NBSP;_SIZE_&NBSP;1024TYPEDEF&NBSP;STRUCT&NBSP;EVENT_BUF{//Self-maintained structure int  fd;char method[10];//http Request method char url[1024];//Request parameter Char parameter[1024];//get method   parameter int  cgi;//need to use cgi  method}ev_buf,*pev_buf;//rename Char* get_text (INT&NBSP;FD,CHAR*&NBSP;BUF);//Get Message body int  epoll_recv_http (Struct epoll_event *ev);//Accept Message Int epoll_echo_http (struct epoll_event  * ev);//Send Xiaoxivoid cgi_action (int fd,char* method,char* url,char*  parameter);//cgi interface int get_Line (int sock_fd,char * buf);//read a row of information from socket fd  void* http_action (void*  Client_sock);//void echo_error (Int fd,int _errno);//Echo error message Void error_all (int fd,int  err,char* reason);//All error messages void echo_html (int fd,const char* url,int size  );//Echo Request webpage #endif

HTTPD.C

#include   "httpd.h" #define  DEFAULT  "/default.html" #define  IMG  "src_html" #define   cgi  "src_cgi" Int times=0;void echo_error (int fd,int _errno) {printf ("join err\n") ; switch (_errno) {case 400://bad request  //client request has a syntax error and cannot be understood by the server break;case 404://// The requested resource does not exist, eg: the wrong url//printf ("*******404\n") was entered, Error_all (fd,404, "not_find!!"); break;case 401://request Unauthorized, this status code must be used with the Www-authenticate header domain  break;case 403://server received the request, but refused to provide service Unexpected error occurred on  break;case 500:// internal server error //server break;case 503:// The server unavailable  //server is currently unable to process client requests and may return to normal break;default:break after a period of time;}} Void error_all (Int fd,int err,char* reason) {char buf[_size_]= ""; Char error[_SIZE _]= ""; sprintf (buf, "http/1.0 %d %s\r\n\r\n", Err,reason); sprintf (Error, " %d %s", Err,reason); printf ("err buf:%s\n error:%s", Buf,error); write (Fd,buf,strlen (BUF)); WRITe (fd, "


Network HTTP Server-v2-epoll version

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.