#include #include #include #include #include #include #include #include #include #include #include #include #include "server.h" #include "user_handler.h" #include "user_manager.h" #define MAX_EVENT_NUMBER 1024 void EpollServer::Loop() { _listenfd= socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); assert(_listenfd!=-1); 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(23410); auto ret=bind(_listenfd,(struct sockaddr*)&server_addr,sizeof(server_addr)); assert(ret!=-1); listen(_listenfd,5); int opt = 1; setsockopt(_listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); _epollfd=epoll_create(5); assert(_epollfd!=-1); addfd(_epollfd,_listenfd,(void *)_listenfd,true); struct epoll_event events[MAX_EVENT_NUMBER]; while(true) { int ret = epoll_wait(_epollfd, events, MAX_EVENT_NUMBER, -1); if(ret<0){ printf("epoll failure\n"); break; } et(events, ret, _epollfd, _listenfd); } close(_listenfd); return; } EpollServer& EpollServer::GetInstance() { static EpollServer server; return server; } void EpollServer::et(struct epoll_event* events, int number, int epollfd, int listenfd) { for (int32_t i = 0; i < number; i++) { int sockfd = events[i].data.fd; if(sockfd==listenfd) { struct sockaddr_in client_address; socklen_t client_addrlength = sizeof(client_address); int connfd = accept(listenfd, (struct sockaddr* )&client_address, &client_addrlength); if(connfd==-1) { return; } CUserHandler *handler=new CUserHandler(connfd); CUserManager::GetInstance().Add(handler); addfd(epollfd,connfd,handler,true); } else if(events[i].events & EPOLLIN) { CUserHandler * handler=reinterpret_cast(events[i].data.ptr); auto ret=handler->Read(); if(ret<0) { epoll_ctl(epollfd,EPOLL_CTL_DEL,handler->Fd(),&events[i]); handler->OnClose(); continue;; } } } } int EpollServer::setnonblocking(int fd) { int old_option = fcntl(fd, F_GETFL); int new_option = old_option | O_NONBLOCK; fcntl(fd, F_SETFL, new_option); return old_option; } void EpollServer::addfd(int epollfd,int fd, void * ptr, int enable_et) { struct epoll_event event; event.data.ptr=ptr; event.events = EPOLLIN; if(enable_et){ event.events |= EPOLLET; } epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &event ); setnonblocking(fd); }