epoll伺服器編程-demo

來源:互聯網
上載者:User

一個簡單的EchoServer. 

在配置的網路地址上監聽(也可以監聽0.0.0.0)

  // create listen  int  init_listen_sock(int epsfd, unsigned short port)  {    std::vector<int> ip_list;    if (!get_ipv4_addr(ip_list))      return 1;    for (int i = 0; i < ip_list.size(); i++)      {        int sfd = 0;        if ((sfd = listen_on(ip_list[i], port)) < 0)          return 1;        int ipv4 = ip_list[i];        unsigned char * pipv4 = (unsigned char *)&ipv4;        LOG_INFO("listen on host: [%d.%d.%d.%d : %d]\n",            pipv4[0],            pipv4[1],            pipv4[2],            pipv4[3],            port            );        if (ep_add(epsfd, sfd, true))          return 1;      }    return 0;  }

建立epoll控制代碼

  int ep_init()  {    return epoll_create(5);  }

添加通訊端到epoll隊列

  int ep_add(int epfd, int sfd, bool is_listen_sock)  {    struct epoll_event evt;    evt.events = EPOLLIN                //| EPOLLOUT                | EPOLLET                  ;    evt.data.ptr = malloc(sizeof(struct epoll_sock_t));    epoll_sock_t * ptr = (epoll_sock_t *) evt.data.ptr;    ptr->sock_fd = sfd;    ptr->listen = is_listen_sock;    int ret = epoll_ctl(epfd, EPOLL_CTL_ADD, sfd, &evt);    return ret;  }

從epoll隊列中刪除通訊端

  int ep_del(int epfd, int sfd)  {    int ret = epoll_ctl(epfd, EPOLL_CTL_DEL, sfd, 0);    return ret;  }

關閉epoll控制代碼

  int ep_shutdown(int epfd)  {    close(epfd);    return 0;  }

在epoll隊列上等待,如果有讀寫事件發生,就回調使用者函數

  int  ep_wait(int epfd, ep_wait_cb_t epw_cb, void * userdata)  {    struct epoll_event evts[EP_MAX_WAIT_NR] = { 0 };    for (;;)      {        int nfds = 0; errno = 0;        if (0 >= (nfds = epoll_wait(epfd, evts, EP_MAX_WAIT_NR, -1)) && errno != EINTR)          {            break;// stop          }        for (int i = 0; i < nfds; i++)          {            epw_cb(epfd, &evts[i], userdata);          }      }  }

一個簡單的啟動線程

void * ep_thread(void * args){  int epfd = 0;  if ((epfd = ep_init()) <= 0)    return 0;  unsigned short port = 8000;  if (init_listen_sock(epfd, port))    {      return 0;    }  void * userdata = 0;  if (ep_wait(epfd, ep_event_callback, userdata))    {      return 0;    }  if (ep_shutdown(epfd))    {      return 0;    };  return (void *)0;}

使用者回呼函數

intep_event_callback(int epfd, struct epoll_event * evt, void * userdata){  epoll_sock_t * ptr = (epoll_sock_t *) (evt->data.ptr);  if (evt->events & EPOLLIN)    {      printsockinfo(ptr->sock_fd);      if (ptr->listen) // for listen socket        {          sockaddr_in csa;          socklen_t csalen = sizeof(csa);          int clientsfd = 0;          errno = 0;          while ((clientsfd = accept(ptr->sock_fd, (struct sockaddr *) &csa, &csalen)) > 0)            {              if (setnonblocking(clientsfd))                {                  LOG_ERROR("fail to set client socket to non-blocking.\n");                  close(clientsfd);                  continue;                }              if (ep_add(epfd, clientsfd, false))                {                LOG_ERROR("fail to add client socket to epoll.\n");                close(clientsfd);                continue;                }            }          if (errno != EAGAIN && errno != EINTR)            close(ptr->sock_fd);        }      else        {          errno = 0;          char msg [0x200] = "";          while (recv(ptr->sock_fd, msg, 0x200, 0) > 0)            {              tm_printstamp();              LOG_INFO(" - %s \r\n", msg);              fflush(stdout);            }          if (errno != EAGAIN && errno != EINTR)            {              close(ptr->sock_fd);              LOG_ERROR("errno=[%d]\n", errno);            }        }    }  else if (evt->events & EPOLLERR)    {      LOG_INFO("catch an EPOLLERR, sockfd=[%d]. errno=[%d]\n", ptr->sock_fd, errno);      close(ptr->sock_fd);    }  else    {      LOG_INFO("epoll events [%d] Ignored, sockfd = [%d].\n", evt->events, ptr->sock_fd);    }  return 0;}

項目源檔案,包括makefile.

http://hi.csdn.net/attachment/201112/30/0_1325239083n82M.gif

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.