Linux 服务器高级编程ET LT代码

 2023-09-07 阅读 24 评论 0

摘要:linux 服务器高级编程ET LT代码 #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<s

linux 服务器高级编程ET LT代码

#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

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/1/12533.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息