linux c++ epoll的簡單實現

    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/select.h>
    #include <sys/time.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <sys/epoll.h>
    #include <errno.h>
    #define OPEN_MAX 100000

int main()
{
    struct epoll_event event;
    struct epoll_event *wait_event;
    int sockfd=socket(AF_INET,SOCK_STREAM,0);
    struct sockaddr_in server_addr;
    server_addr.sin_family=AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port=htons(8001);
    bind(sockfd,(struct sockaddr*)&server_addr,sizeof(server_addr));
    listen(sockfd,100);
    int sockNumber[OPEN_MAX]={0};
    sockNumber[0]=sockfd;
    int crRet=epoll_create(10);
    if(-1==crRet)
    {
        perror("創建文件描述符失敗");
        return 0;
    }
    event.data.fd=sockfd;
    event.events=EPOLLIN;
    int clRet=epoll_ctl(crRet,EPOLL_CTL_ADD,sockfd,&event);
    if(-1==clRet)
    {
        perror("註冊監聽事件類型失敗");
    }
    int max1=0;
    char buf[1024]={0};
    while(1)
    {   wait_event=new epoll_event[max1+1];
        clRet=epoll_wait(crRet,wait_event,max1+1,-1);
        for(int i=0;i<clRet;i++)
        {
            if((sockfd==wait_event[i].data.fd)&&(EPOLLIN==wait_event[i].events&EPOLLIN))
             {   struct sockaddr_in cli_addr;
                  socklen_t length = sizeof(cli_addr);
                  sockNumber[max1+1]=accept(sockfd,(struct sockaddr*)&cli_addr,&length);
                  if(sockNumber[max1+1]>0)
                  {
                       event.data.fd = sockNumber[max1+1];
                       event.events = EPOLLIN;
                       int ret1 = epoll_ctl(crRet, EPOLL_CTL_ADD, sockNumber[max1+1], &event);
                       max1++;
                       if(-1==ret1)
                       {
                           perror("新連接的客戶端註冊失敗");
                       }
                       printf("客戶端%d上線\n",max1);
                  }
             }
            else if(wait_event[i].data.fd>3&&( EPOLLIN == wait_event[i].events & (EPOLLIN|EPOLLERR)))
              {      memset(buf,0,sizeof(buf));
                     int len=recv(wait_event[i].data.fd,buf,sizeof(buf),0);
                     if(len<=0)
                      {
                            for(int j=1;j<=max1;j++)
                             {
                                  if(wait_event[i].data.fd==sockNumber[j])
                                    {
                                            clRet=epoll_ctl(crRet,EPOLL_CTL_DEL,wait_event[i].data.fd,wait_event+i);
                                            printf("客戶端%d下線\n",max1);
                                            sockNumber[j] =sockNumber[max1] ;
                                            close(sockNumber[max1]);
                                            sockNumber[max1] =-1;
                                            max1--;
                                            usleep(50000);
                                    }
                             }
                      }
                   else
                     {
                      printf("%s\n",buf);
                     }
           }
        }
        delete[] wait_event;
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章