I/O多路转接之epoll模型

来源:互联网 发布:mac照片是什么意思啊 编辑:程序博客网 时间:2024/06/04 20:06

epoll是性能最好的没有之一
epoll有三个系统调用函数
epoll_create 创建文件描述符、来标识epoll模型
epoll_ctl
epoll_wait
这里写图片描述

#include<stdio.h>#include <sys/epoll.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/time.h>#include <sys/types.h>#include <unistd.h>#include<arpa/inet.h>#include<netinet/in.h>#include<string.h>#include<unistd.h>#include<stdlib.h>#define SIZE 64static void Usage(char*proc){    printf("%s [local_ip] [local_port]\n",proc);}int startUp(char*ip,int port){   int sock=socket(AF_INET,SOCK_STREAM,0);    if(sock<0)    {        perror("socket");        exit(2);    }    int opt=1;    setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));    struct sockaddr_in server;    server.sin_family=AF_INET;    server.sin_port=htons(atoi(port));    server.sin_addr.s_addr=inet_addr(ip);    if(bind(sock,(struct sockaddr*)&server,sizeof(struct sockaddr_in))<0)    {        perror("bind");        exit(3);    }    if(listen(sock,10)<0)    {        perror("listen");        exit(4);    }    return sock;}int main(int argv,char*argc[]){    if(argv!=3)    {        Usage(argc[0]);        return 1;    }    int listen_sock=startUp(argc[1],argc[2]);    int epfd= epoll_create(256);    if(epfd<0)    {       perror("epoll_create");       return 5;    }    struct epoll_event ev;    ev.events=EPOLLIN;    ev.data.fd=listen_sock;    epoll_ctl(epfd,EPOLL_CTL_ADD,listen_sock,&ev);    struct epoll_event revs[64];      int nums=-1;    int timeout=5000;    while(1)    {        switch((nums=epoll_wait(epfd,revs,SIZE,timeout)))        {           case -1:               perror("epoll_wait");               return 6;           case 0:               printf("timeout\n");               break;            default:               {               int i=0;               for(i=0;i<nums;i++)               {                   printf("nums %d\n",nums);                   int fd=revs[i].data.fd;                   if(fd==listen_sock&&revs[i].events&EPOLLIN)                   {                          struct sockaddr_in client;                          socklen_t len=sizeof(client);                          int newsock=accept(listen_sock,(struct sockaddr*)&client,&len);                          if(newsock<0)                          {                              perror("accept");                              continue;                          }                          printf("get a client [%s] [%d]\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port));                          ev.events=EPOLLIN;                          ev.data.fd=newsock;                          epoll_ctl(epfd,EPOLL_CTL_ADD,newsock,&ev);                   }                else if(fd!=listen_sock)                   {                       printf("hahah\n");                       if(revs[i].events&EPOLLIN)                       {                          char buf[1024];                          ssize_t s=read(fd,buf,sizeof(buf)-1);                          if(s>0)                          {                              buf[s]=0;                              printf("client say:%s\n",buf);                              ev.events=EPOLLOUT;                              ev.data.fd=fd;                              epoll_ctl(epfd, EPOLL_CTL_MOD,fd,&ev);                          }                          else if(s==0)                          {                              printf("client is quit\n");                              close(fd);                              epoll_ctl(epfd,EPOLL_CTL_DEL,fd,&ev);                          }                          else                          {                              perror("read");                              close(fd);                              epoll_ctl(epfd,EPOLL_CTL_DEL,fd,&ev);                       }                       }                       else if(revs[i].events&EPOLLOUT)                       {                             const char* msg = "HTTP/1.1 200 OK\r\n\r\n<html><h1>Hello epoll!</h1></html>";                              write(fd,msg,strlen(msg));                              close(fd);                              epoll_ctl(epfd,EPOLL_CTL_DEL,fd,&ev);                       }                       else                       {                       }                   }                   else                   {                   }               }               }             break;        }    }    return 0;}

epolls是一种高性能服务器。
1、他底层的红黑树能够高效的进行增删改查
2、采用回调机制不需要轮询
3、一旦关心的文件描述符上对应的事件发生就激活放入就绪队列
4、上层直接从就绪队列中取
5、就绪队列连续并且返回值是实际就绪的个数,这样即使需要遍历也会遍历的都是有效的
6、采用内存映射机制,少了数据的拷贝。

原创粉丝点击