Linux c++ epoll 模型demo
来源:互联网 发布:linux telnet 安装 编辑:程序博客网 时间:2024/06/06 04:28
部分代码复用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;}
阅读全文
0 0
- Linux c++ epoll 模型demo
- Linux的EPoll模型
- [转]linux epoll模型
- linux epoll 模型详解
- Linux的EPoll模型
- [转]:linux epoll模型
- linux epoll模型
- linux epoll模型
- linux epoll模型
- Linux的epoll模型
- linux epoll模型
- Linux epoll模型
- Linux的epoll模型
- linux epoll模型
- [转]linux epoll模型
- Linux的epoll模型
- linux epoll模型
- linux epoll模型
- MySQL 索引的那点知识
- java并发编程实战-线程池的使用2
- POJ—1426
- R
- win10自带虚拟机安装ubuntu系统
- Linux c++ epoll 模型demo
- 【剑指offer】二叉搜索树与双向链表
- 常见C++面试题及基本知识点总结(一)
- 康托展开
- 【JZOJ2702】【GDKOI2012模拟02.01】探险
- 高斯混合模型实践(Python)
- 多路复用IO
- 模拟退火板子 poj1379 hdu 5017 hdu2899
- 【JZOJ4427/HNOI2016模拟】 Alphadog