Linux c++ epoll 模型demo
2017-07-15 22:13
323 查看
部分代码复用select的代码
核心代码如下
核心代码如下
#include <unistd.h> #include <sys/types.h> #include <fcntl.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <signal.h> #include <fcntl.h> #include <sys/wait.h> #include <sys/epoll.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <vector> #include <algorithm> #include <iostream> #include "socket.h" typedef std::vector<struct epoll_event> EPOLL_FD_VECTOR; int main(void) { InitErrDeal(); int s32ServerSocket = -1; InitServerSocket(s32ServerSocket); std::vector<int> clients; int s32EpollFd; s32EpollFd = epoll_create1(EPOLL_CLOEXEC); struct epoll_event stEvent; stEvent.data.fd = s32ServerSocket; stEvent.events = EPOLLIN;/*水平触发, | EPOLLET边沿触发*/ epoll_ctl(s32EpollFd, EPOLL_CTL_ADD, s32ServerSocket, &stEvent); EPOLL_FD_VECTOR vecEpollEvents(16); int s32ActiveFd; int s32ActiveFdNum; while (1) { s32ActiveFdNum = epoll_wait(s32EpollFd, &*vecEpollEvents.begin(), static_cast<int>(vecEpollEvents.size()), -1); if (s32ActiveFdNum > 0) { //一次性返回的事件队列满了,会分成多次返回 if ((size_t)s32ActiveFdNum == vecEpollEvents.size()) { vecEpollEvents.resize(vecEpollEvents.size()*2); } for (int i = 0; i < s32ActiveFdNum; ++i) { if (vecEpollEvents[i].data.fd == s32ServerSocket)//有连接事件 { struct sockaddr_in stClientAddr; socklen_t Addrlen = sizeof(struct sockaddr_in); s32ActiveFd = ::accept4(s32ServerSocket, (struct sockaddr*)&stClientAddr, &Addrlen, SOCK_NONBLOCK | SOCK_CLOEXEC); if (s32ActiveFd == -1) { //进程打开描述符到达上限处理 if (errno == EMFILE) { ERR_INFO_S stErrInfo; stErrInfo.enErrType = ERR_EMFILE; stErrInfo.pvUserData = (void *)&s32ActiveFd; ProcessErr(stErrInfo); continue; } else { SHOW_ERR("accept4 err!\n"); continue; } } SHOW_SOCKADDR_INFO(stClientAddr); clients.push_back(s32ActiveFd); stEvent.data.fd = s32ActiveFd; stEvent.events = EPOLLIN;/* | EPOLLET*/ epoll_ctl(s32EpollFd, EPOLL_CTL_ADD, s32ActiveFd, &stEvent); } else if (vecEpollEvents[i].events & EPOLLIN)//可读 { s32ActiveFd = vecEpollEvents[i].data.fd; char szContent[256]={0}; int s32Ret = ::recv(s32ActiveFd, szContent, sizeof(szContent), 0); //使用read也可以 if (s32Ret > 0) { szContent[s32Ret] = '\0'; INFO_PRINT("recv %d:%s\n",s32Ret, szContent); ::send(s32ActiveFd, szContent, s32Ret, 0); //使用write也行 } else //异常或关闭的 { ::close(s32ActiveFd); stEvent = vecEpollEvents[i]; epoll_ctl(s32EpollFd, EPOLL_CTL_DEL, s32ActiveFd, &stEvent); clients.erase(std::remove(clients.begin(), clients.end(), s32ActiveFd), clients.end()); INFO_PRINT("close[%d]\n",s32ActiveFd); } } } } //timeout else if (s32ActiveFdNum == 0) { continue; } else { if (errno == EINTR) { continue; } SHOW_ERR("\n"); return FAILURE; } } return SUCCESS; }
相关文章推荐
- C++ - 网络编程模型 - Linux EPOLL - - ITeye技术网站
- C++ linux epoll并发服务器模型初探
- C++ - 网络编程模型 - Linux EPOLL
- C++ - 网络编程模型 - Linux EPOLL
- [转]C++ - 网络编程模型 - Linux EPOLL
- linux c/c++网络编程之—epoll 模型
- C++ - 网络编程模型 - Linux EPOLL
- Linux -- epoll 事件模型详解
- epoll定时器实现系列文章:linux c++ 利用timerfd和epoll封装计时器(Timer)类
- linux基础编程:IO模型:阻塞/非阻塞/IO复用 同步/异步 Select/Epoll/AIO
- (OK) Linux epoll模型—socket epoll server client chat
- Linux 下Epoll模型
- linux c/c++网络编程之—线程池模型
- Linux网络编程--epoll 模型原理详解以及实例
- Linux下select, poll和epoll IO模型的详解
- Linux高并发机制—epoll模型详解
- linux epoll 模型介绍及程序实例
- Linux的epoll模型
- linux epoll 模型详解
- Linux下select, poll和epoll IO模型的详解