#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<assert.h>
#include<stdio.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>
#include<fcntl.h>
#include<stdlib.h>
#include<sys/epoll.h>
#include<pthread.h>#define MAX_EVENT_NUMBER 1024
#define BUFFER_SIZE 10int 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 addfd(int epollfd, int fd, bool enable_et) //在内核事件表中为fd注册事件
{epoll_event event;event.data.fd = fd;event.events = EPOLLIN;if (enable_et){event.events |= EPOLLET;}epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &event); // 操作内核事件表的函数setnonblocking(fd);
}void lt(epoll_event* events, int number, int epollfd, int listenfd)
{char buf[BUFFER_SIZE];for (int 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);addfd(epollfd, connfd, false);printf("connect fd:%d listenfd=%d\n", connfd, listenfd);} else if (events[i].events & EPOLLIN) {printf("event trigger once\n");memset(buf, '\0', BUFFER_SIZE);int ret = recv(sockfd, buf, BUFFER_SIZE - 1, 0);printf("socket fd:%d listenfd=%d\n", sockfd, listenfd);if (ret < 0) {close(sockfd);continue;}printf("get %d bytes of content: %s\n", ret, buf);} else {printf("sth else happend\n");}}
}void et(epoll_event* events, int number, int epollfd, int listenfd)
{char buf[BUFFER_SIZE];for (int 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);addfd(epollfd, connfd, true);} else if (events[i].events & EPOLLIN) {printf("event trigger once\n");while (1) {memset(buf, '\0', BUFFER_SIZE);int ret = recv(sockfd, buf, BUFFER_SIZE - 1, 0);if (ret < 0) {if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {printf("read later\n");break;}close(sockfd);break;} else if (ret == 0) {close(sockfd);} else {printf("get %d bytes of content:%s\n", ret, buf);}}} else {printf("nothing happend\n");}}
}int main(int argc, char* argv[])
{if (argc <= 2) {printf("usage: %s ip_address port_number\n", basename(argv[0]));return 1;}const char* ip = argv[1];int port = atoi(argv[2]);int ret = 0;struct sockaddr_in address;bzero(&address, sizeof(address));address.sin_family = AF_INET;inet_pton(AF_INET, ip, &address.sin_addr);address.sin_port = htons(port);int listenfd = socket(PF_INET, SOCK_STREAM, 0);assert(listenfd >= 0);ret = bind(listenfd, (struct sockaddr*)&address, sizeof(address));assert(ret != -1);ret = listen(listenfd, 5);assert(ret != -1);epoll_event events[MAX_EVENT_NUMBER];int epollfd = epoll_create(5);addfd(epollfd, listenfd, true);while(1) {int ret = epoll_wait(epollfd, events, MAX_EVENT_NUMBER, -1);if (ret < 0) {printf("epoll fail\n");break;}// lt(events, ret, epollfd, listenfd);et(events, ret, epollfd, listenfd);}close(listenfd);return 0;
}
ET:
ET模式下需要一次性处理完所有数据,下次就不会加入到epoll_wait的事件中了。
LT:
LT模式下未处理完的事件还是会被加入到epoll_wait监听的事件中。
centos代码,reference:
linux高性能服务器编程——游双P153-P157
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态