当前位置:网站首页>Epoll's et, lt working mode -- example program
Epoll's et, lt working mode -- example program
2022-04-23 14:40:00 【m0_ fifty-one million five hundred and fifty-one thousand three】
The following is a server program , It can be done by LT
or ET
Two modes receive the data sent by the client , And print to standard output .
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<assert.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<netinet/in.h>
#include<errno.h>
#include<arpa/inet.h>
#include<fcntl.h>
#include<sys/epoll.h>
#include<pthread.h>
#define MAX_EVENT_NUMBER 1024
#define BUFFER_SIZE 10
/* Set the file descriptor to non blocking */
int 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;
}
/* File descriptors fd Upper EPOLLIN Sign up to epollfd Directed epoll In the kernel event table , Parameters enable_et Specify whether or not fd Enable ET Pattern */
void addfd(int epollfd, int fd, bool enable_et)
{
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);
}
/* LT Pattern workflow */
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); /* hold connfd Add to the kernel event table , And disable ET Pattern */
}
else if (events[i].events & EPOLLIN)
{
/* as long as socket There is still unread data in the read cache , This code is triggered */
printf("EPOLLIN event trigger once\n");
memset(buf, '\0', BUFFER_SIZE);
int ret = recv(sockfd, buf, BUFFER_SIZE - 1, 0);
if (ret <= 0)
{
close(sockfd);
continue;
}
printf("get %d bytes of content: %s\n", ret, buf);
}
else
{
printf("something else happened \n");
}
}
}
/* ET Mode workflow */
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(sockfd, (struct sockaddr*)&client_address, &client_addrlength);
addfd(epollfd, connfd, true); /* hold connfd Add to the kernel event table , And open ET Pattern */
}
else if (events[i].events & EPOLLIN)
{
/* This code will not be triggered repeatedly , So you have to cycle through the data , To make sure that socket Read all data in the cache */
printf("EPOLLIN event trigger once\n");
while (1)
{
memset(buf, '\0', BUFFER_SIZE);
int ret = recv(sockfd, buf, BUFFER_SIZE - 1, 0);
if (ret < 0)
{
/* For non blocking IO, If the following conditions are true, it means that all data has been read . thereafter ,epoll You can trigger it again sockfd Upper EPOLLIN event , Perform the next read operation */
if (errno == EAGAIN || errno == EWOULDBLOCK)
{
printf("raed later\n");
break;
}
close(sockfd);
break;
}
else if (ret == 0) /* return 0, Indicates that the other party has closed the connection */
{
close(sockfd);
}
else
{
printf("get %d bytes of content: %s\n", ret, buf);
}
}
}
else
{
printf("something else happened \n");
}
}
}
int main(int argc, char* argv[])
{
if (argc <= 2)
{
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;
address.sin_port = htons(port);
inet_pton(AF_INET, ip, &address.sin_addr);
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(10);
assert(epollfd != -1);
addfd(epollfd, listenfd, true);
while (1)
{
int ret = epoll_wait(epollfd, events, MAX_EVENT_NUMBER, -1);
if (ret < 0)
{
printf("epoll filure\n");
break;
}
// lt(events, ret, epollfd, listenfd);
et(events, ret, epollfd, listenfd);
}
close(listenfd);
return 0;
}
版权声明
本文为[m0_ fifty-one million five hundred and fifty-one thousand three]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204231435333921.html
边栏推荐
猜你喜欢
Swift - Literal,字面量协议,基本数据类型、dictionary/array之间的转换
51单片机的直流电机PWM调速控制系统(附Proteus仿真+C程序等全套资料)
Svn detailed use tutorial
Design of single chip microcomputer Proteus for temperature and humidity monitoring and alarm system of SHT11 sensor (with simulation + paper + program, etc.)
we引用My97DatePicker 实现时间插件使用
Eight way responder system 51 Single Chip Microcomputer Design [with Proteus simulation, C program, schematic diagram, PCB files, component list and papers, etc.]
A blog allows you to learn how to write markdown on vscode
Swift:Entry of program、Swift调用OC、@_silgen_name 、 OC 调用Swift、dynamic、String、Substring
MQ-2和DS18B20的火灾温度-烟雾报警系统设计,51单片机,附仿真、C代码、原理图和PCB等
8.3 语言模型与数据集
随机推荐
金九银十,入职字节跳动那一天,我哭了(蘑菇街被裁,奋战7个月拿下offer)
MCU function signal generator, output four kinds of waveforms, adjustable frequency, schematic diagram, simulation and C program
《JVM系列》 第七章 -- 字节码执行引擎
Basic regular expression
自动化的艺术
单片机的函数信号发生器,输出4种波形,频率可调,原理图,仿真和C程序
OpenFaaS实战之四:模板操作(template)
交通灯系统51单片机设计(附Proteus仿真、C程序、原理图及PCB、论文等全套资料)
PCIe X1 插槽的主要用途是什么?
Raised exception class eaccexviolation with 'access violation at address 45efd5 in module error
Interviewer: let's talk about the process of class loading and the mechanism of class loading (parental delegation mechanism)
Using MATLAB programming to realize the steepest descent method to solve unconstrained optimization problems
MDS55-16-ASEMI整流模块MDS55-16
LotusDB 设计与实现—1 基本概念
Nacos uses demo as configuration center (IV)
初识STL
C语言知识点精细详解——数据类型和变量【1】——进位计数制
顺序栈的基本操作
直流可调稳压电源的Proteus仿真设计(附仿真+论文等资料)
Branch statement of process control