server.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #include <string.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <sys/select.h>
  6. #include <sys/time.h>
  7. #include <sys/socket.h>
  8. #include <netinet/in.h>
  9. #include <arpa/inet.h>
  10. #include <sys/epoll.h>
  11. #include <assert.h>
  12. #include <fcntl.h>
  13. #include "server.h"
  14. #include "user_handler.h"
  15. #include "user_manager.h"
  16. #define MAX_EVENT_NUMBER 1024
  17. void EpollServer::Loop()
  18. {
  19. _listenfd= socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  20. assert(_listenfd!=-1);
  21. struct sockaddr_in server_addr;
  22. server_addr.sin_family=AF_INET;
  23. server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  24. server_addr.sin_port=htons(23410);
  25. auto ret=bind(_listenfd,(struct sockaddr*)&server_addr,sizeof(server_addr));
  26. assert(ret!=-1);
  27. listen(_listenfd,5);
  28. int opt = 1;
  29. setsockopt(_listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
  30. _epollfd=epoll_create(5);
  31. assert(_epollfd!=-1);
  32. addfd(_epollfd,_listenfd,(void *)_listenfd,true);
  33. struct epoll_event events[MAX_EVENT_NUMBER];
  34. while(true)
  35. {
  36. int ret = epoll_wait(_epollfd, events, MAX_EVENT_NUMBER, -1);
  37. if(ret<0){
  38. printf("epoll failure\n");
  39. break;
  40. }
  41. et(events, ret, _epollfd, _listenfd);
  42. }
  43. close(_listenfd);
  44. return;
  45. }
  46. EpollServer& EpollServer::GetInstance()
  47. {
  48. static EpollServer server;
  49. return server;
  50. }
  51. void EpollServer::et(struct epoll_event* events, int number, int epollfd, int listenfd)
  52. {
  53. for (int32_t i = 0; i < number; i++)
  54. {
  55. int sockfd = events[i].data.fd;
  56. if(sockfd==listenfd)
  57. {
  58. struct sockaddr_in client_address;
  59. socklen_t client_addrlength = sizeof(client_address);
  60. int connfd = accept(listenfd, (struct sockaddr* )&client_address, &client_addrlength);
  61. if(connfd==-1)
  62. {
  63. return;
  64. }
  65. CUserHandler *handler=new CUserHandler(connfd);
  66. CUserManager::GetInstance().Add(handler);
  67. addfd(epollfd,connfd,handler,true);
  68. }
  69. else if(events[i].events & EPOLLIN)
  70. {
  71. CUserHandler * handler=reinterpret_cast<CUserHandler *>(events[i].data.ptr);
  72. auto ret=handler->Read();
  73. if(ret<0)
  74. {
  75. epoll_ctl(epollfd,EPOLL_CTL_DEL,handler->Fd(),&events[i]);
  76. handler->OnClose();
  77. continue;;
  78. }
  79. }
  80. }
  81. }
  82. int EpollServer::setnonblocking(int fd)
  83. {
  84. int old_option = fcntl(fd, F_GETFL);
  85. int new_option = old_option | O_NONBLOCK;
  86. fcntl(fd, F_SETFL, new_option);
  87. return old_option;
  88. }
  89. void EpollServer::addfd(int epollfd,int fd, void * ptr, int enable_et)
  90. {
  91. struct epoll_event event;
  92. event.data.ptr=ptr;
  93. event.events = EPOLLIN;
  94. if(enable_et){
  95. event.events |= EPOLLET;
  96. }
  97. epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &event );
  98. setnonblocking(fd);
  99. }