函数说明:创建一个树,返回一个树根节点
函数参数:
size:必须传一个>0的数;
返回值:
成功返回一个文件描述符,这个文件描述符就表示epoll树的数根节点;
- RETURN VALUE
- On success, these system calls return a nonnegative file descriptor.
- On error, -1 is returned, and errno is set to indicate the error.
函数说明:能把fd上epoll树,从树上删除和修改
函数参数:
epfd:树根节点
op:
- Valid values for the op argument are:
-
- EPOLL_CTL_ADD//上树
- Add fd to the interest list and associate the settings speci‐
- fied in event with the internal file linked to fd.
-
- EPOLL_CTL_MOD//修改
- Change the settings associated with fd in the interest list to
- the new settings specified in event.
-
- EPOLL_CTL_DEL//从树上删除文件描述符(节点)
- Remove (deregister) the target file descriptor fd from the in‐
- terest list. The event argument is ignored and can be NULL
- (but see BUGS below).
fd:要操作的文件描述符
event
struct epoll_event {
uint32_t events; /* Epoll events */
epoll_data_t data; /* User data variable */
};
event.events:
- typedef union epoll_data {
- void *ptr;
- int fd;//委托内核监控的文件描述符
- uint32_t u32;
- uint64_t u64;
- } epoll_data_t;
使用:
struct epoll_event ev;
ev. events=EPOLLIN;//可读事件
ev.data.fd=fd;//委托内核监控文件描述符
epoll_ctl(epfd,EPOLL_CTL_ADD,fd,&ev);
函数说明:委托内核监控epoll树的事件节点
函数参数:
epfd:epoll树根节点
events:传出参数,结构体数组,把发生变化的文件描述符放入传出参数events.data.fd
maxevents:events数组大小
timeout:
注意:epoll_wait函数返回数组中事件节点的值不会被修改,是当时上epoll树的时候建立的值。
返回值:
- When successful, epoll_wait() returns the number of file descriptors
- ready for the requested I/O
返回发生变化的文件描述符的数量。
可以确切的知道发生的变化的文件描述符,就不用遍历了
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- int main()
- {
- int lfd=socket(AF_INET,SOCK_STREAM,0);
- if(lfd<0)
- {
- perror("socket error");
- return -1;
- }
- int opt=1;
- setsockopt(lfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(int));
- struct sockaddr_in sev;
- sev.sin_family=AF_INET;
- sev.sin_port=htons(8888);
- inet_pton(AF_INET,"192.168.230.130",&sev.sin_addr.s_addr);
- int ret=bind(lfd,(struct sockaddr*)&sev,sizeof(sev));
- if(ret<0)
- {
- perror("bind error");
- return -1;
- }
- ret=listen(lfd,128);
- if(ret<0)
- {
- perror("listen error");
- return -1;
- }
-
- int epfd=epoll_create(1);//创建一个epoll树
- if(epfd<0)
- {
- perror("epoll_create error");
- return -1;
- }
- //int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
- struct epoll_event event;
- event. events= EPOLLIN;//让内核监控lfd的可读事件
- event.data.fd=lfd;
-
- ret=epoll_ctl(epfd, EPOLL_CTL_ADD,lfd,&event);//lfd上树
- int cfd;
- struct epoll_event e[1024];//创建数组
- int nready;
- int i;
- int sockfd;
- int n;
- int j;
- char buf[64];
- while(1)
- {
- // int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
- nready=epoll_wait(epfd,e,1024,-1);//返回发生变化的文件描述符的数量,并且可以确切的知道是哪些文件描述符发生变化,只有发生变化的文件描述符存放到e数组中
- if(nready<0)
- {
- if(errno==EINTR)//被信号打断
- {
- continue;
- }
- break;
- }
- for(i=0;i
- {
- sockfd=e[i].data.fd;
- if(sockfd==lfd)//有客户端连接请求
- {
- cfd=accept(lfd,NULL,NULL);
-
- event. events=EPOLLIN;//让内核监控cfd的可读事件
- event.data.fd=cfd;
- ret=epoll_ctl(epfd, EPOLL_CTL_ADD,cfd,&event);//将cfd上树
- continue;//继续for循环
-
- }
- //客户端发来数据
- memset(buf,0x00,sizeof(buf));
- n=read(sockfd,buf,sizeof(buf));
- if(n<=0)
- {
- printf("read error or client close,n==[%d]\n",n);
- close(sockfd);//关闭此cfd
- epoll_ctl(epfd,EPOLL_CTL_DEL,cfd,NULL);//并将此cfd下树,不再让内核监控
- }
- else
- {
- printf("n==[%d],buf==[%s]\n",n,buf);
- for(j=0;j
- {
- buf[j]=toupper(buf[j]);
- }
- write(sockfd,buf,strlen(buf));
- }
- }
- }
- close(lfd);
- return 0;
- }
结果:
-
相关阅读:
AutoSAR入门:开发工具链介绍
【密评】商用密码应用安全性评估从业人员考核题库(十五)
SpringBoot+MyBatis flex实现简单增删改查
【学习笔记】 - 基础数据结构 :Link-Cut Tree(进阶篇)
随手笔记-Jackson -> @JsonFormat -> 失真问题解决
R语言Bootstrap、百分位Bootstrap法抽样参数估计置信区间分析通勤时间和学生锻炼数据
Unity 游戏设计模式:观察者模式
GO的安装和配置
在线问题反馈模块实战(九):实现图片上传功能(下)
安卓考试答题APP源码
-
原文地址:https://blog.csdn.net/luosuss/article/details/136591292