Epoll LT和ET模式

来源:互联网 发布:淘宝清仓报名 编辑:程序博客网 时间:2024/05/01 22:03

关于epoll解说请参考:

点击打开链接

下面是使用实例,也可以参考man epoll Ubuntu上的实例

#define BUFFSIZE 1024#define PORT 5588using namespace std;#define ERR_EXIT(a) do \{ \printf("%s", a); \} while (0);typedef vector<struct epoll_event> EventList;template<typename T>void log(T msg){cout<<msg<<endl;}void activate_nonblock(int fd)  {      int ret;      int flags=fcntl(fd,F_GETFL);      if(flags == -1)      {          ERR_EXIT("fcntl");          }      flags |= O_NONBLOCK;      ret = fcntl(fd,F_SETFL,flags);      if(ret ==-1)      {          ERR_EXIT("fcntl");      }        } int initSock(){int fd = socket(AF_INET, SOCK_STREAM, 0);struct sockaddr_in sockaddr_t;memset(&sockaddr_t, 0, sizeof(sockaddr_t));sockaddr_t.sin_family = AF_INET;sockaddr_t.sin_port = htons(PORT);sockaddr_t.sin_addr.s_addr = htonl(INADDR_ANY);/*设置为非阻塞*/// int flags = fcntl(fd, F_GETFL, 0);// fcntl(fd, F_SETFL, flags|O_NONBLOCK);//设置地址重复利用int on = 1;if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0){log("setsockopt");}if (bind(fd, (struct sockaddr*)&sockaddr_t, sizeof(sockaddr_t)) < 0 ){log("bind is failed");return -1;}if(listen(fd, SOMAXCONN) < 0){log("listen is failed");return -1;}return fd;}int acceptPool(int fd){int acceptfd;struct sockaddr_in clientAddr;socklen_t len = sizeof(clientAddr);char readbuff[BUFFSIZE];EventList events(10);struct epoll_event ev;int epollfd = epoll_create1(EPOLL_CLOEXEC);ev.events = EPOLLIN;//设置关注事件ev.data.fd = fd;if(epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) < 0){log("epoll_ctl is errno");exit(EXIT_FAILURE);}int retVal = 0;while(1){retVal = epoll_wait(epollfd, &*events.begin(), static_cast<int>(events.size()), -1);if (retVal < 0 && errno == EINTR){continue;}else if (retVal < 0){log("epoll_wait is errno");return -1;}if (events.size() == retVal){events.resize(events.size() * 2);}cout<<"things size is :"<<events.size()<<endl;for (int i = 0; i < events.size(); ++i){if (events[i].data.fd == fd){acceptfd = accept(events[i].data.fd, (struct sockaddr*)&clientAddr,&len);if (acceptfd < 0){log("accept is errno");return -1;}activate_nonblock(acceptfd);ev.data.fd = acceptfd;ev.events = EPOLLIN; //设置关注事件epoll_ctl(epollfd, EPOLL_CTL_ADD, acceptfd, &ev); //将新的连接添加到关注的集合log("have a client connect");}else if (events[i].events & EPOLLIN){memset(readbuff, 0, sizeof(readbuff));int ret = read(events[i].data.fd, readbuff, sizeof(readbuff));if (ret < 0){log("read erron");break;}else if (ret == 0){log("close a client");close(events[i].data.fd);epoll_ctl(epollfd, EPOLL_CTL_DEL, events[i].data.fd, &events[i]);continue;}log(readbuff);write(events[i].data.fd, readbuff, strlen(readbuff));}}}return 0;}int main(int argc, char const *argv[]){int fd = initSock();acceptPool(fd);return 0;}

epoll LT 模式:水平触发,当内核缓冲区为空时(write)或为满时(read)触发



epoll ET模式:边缘触发,当内核缓冲区为由满到空时(write)或为由空到满时(read)触发


0 0
原创粉丝点击