- 论坛徽章:
- 0
|
本帖最后由 fuyuande 于 2018-06-12 20:28 编辑
根据相关的资料得知,当epoll监听的对象设置为水平触发时(默认是水平触发),当发生可读事件并且没有将数据读取完毕,epoll会多次触发,直到数据读完,这一点在测试的监听标准输入的时候得到验证。代码如下:
- #include <sys/epoll.h>
- #include <sys/types.h>
- #include <sys/errno.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
- #include <stdio.h>
- #define BUFFER_SIZE 512
- #define log(fmt, arg...) printf(""fmt, ##arg)
- void main(){
- int efd, fds, i, fd;
- int ret;
- struct epoll_event g_event; // epoll事件
- struct epoll_event *epoll_events_ptr;
- char buffer[BUFFER_SIZE] = {0};
- efd = epoll_create1(0); //创建epoll实例
- if (efd == -1) {
- log("create epoll fail \r\n");
- goto err;
- }
- log("create epoll instance success \r\n");
-
- epoll_events_ptr = (struct epoll_event *)calloc(2, sizeof(struct epoll_event));
- if (epoll_events_ptr == NULL) {
- log("calloc fail \r\n");
- goto err;
- }
- g_event.data.fd = STDIN_FILENO; //监听标准输入
- g_event.events = EPOLLIN; //默认水平触发
- epoll_ctl(efd, EPOLL_CTL_ADD, STDIN_FILENO, &g_event);
- while(1) { //监听epoll事件
- fds = epoll_wait(efd, epoll_events_ptr, 2, -1);
- for (i = 0; i<fds; i++)
- {
- if (epoll_events_ptr[i].events & EPOLLIN)
- {
- ret = read(STDIN_FILENO, buffer, 1);
- if(ret != -1)
- log("recv msg : %s \n", buffer);
- }
- memset(buffer, 0, BUFFER_SIZE);
- }
- }
-
- err:
- if(epoll_events_ptr)
- free(epoll_events_ptr);
- return ;
- }
复制代码
但是测试监听udp套接字的时候,当向套接字发送多个数据,每次只读取一个,epoll只触发了一次,同样是水平触发,不清楚为什么udp套接字没有多次触发,代码:
- #include <netinet/in.h>
- #include <sys/socket.h>
- #include <sys/epoll.h>
- #include <sys/types.h>
- #include <arpa/inet.h>
- #include <sys/errno.h>
- #include <stdint.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
- #define BUFFER_SIZE 512
- #define log(fmt, arg...) printf(""fmt, ##arg)
- void main(){
- int fd1,efd, fds, i, fd;
- int ret, addr_len;
- struct epoll_event g_event; // epoll事件
- struct epoll_event *epoll_events_ptr;
- char buffer[BUFFER_SIZE] = {0};
- struct sockaddr_in addr1;
- fd1 = socket(AF_INET, SOCK_DGRAM, 0); //创建套接字
- if (fd1 == -1) {
- log("create socket fail \r\n");
- return ;
- }
- addr1.sin_family = AF_INET; //设置本地地址与端口
- addr1.sin_addr.s_addr = INADDR_ANY;
- addr1.sin_port = htons(3500);
- addr_len = sizeof(struct sockaddr_in);
-
- if (0 != bind(fd1, (struct sockaddr *)&addr1, sizeof(struct sockaddr_in))) {
- log("bind local listening addr fail,errno : %d \r\n", errno);
- goto err;
- }
- efd = epoll_create1(0); //创建epoll实例
- if (efd == -1) {
- log("create epoll fail \r\n");
- goto err;
- }
- log("create epoll instance success \r\n");
-
- epoll_events_ptr = (struct epoll_event *)calloc(2, sizeof(struct epoll_event));
- if (epoll_events_ptr == NULL) {
- log("calloc fail \r\n");
- goto err;
- }
- g_event.data.fd = fd1;
- g_event.events = EPOLLIN | EPOLLET; //水平触发
- epoll_ctl(efd, EPOLL_CTL_ADD, fd1, &g_event);
- while(1) {
- fds = epoll_wait(efd, epoll_events_ptr, 2, -1); //阻塞
- for (i = 0; i<fds; i++)
- {
- if (epoll_events_ptr[i].events & EPOLLIN)
- {
- ret = read(fd1, buffer, 1);
- if(ret != -1)
- log("recv msg : %s \n", buffer);
- }
- memset(buffer, 0, BUFFER_SIZE);
- }
- }
-
- err:
- close(fd1);
- if(epoll_events_ptr)
- free(epoll_events_ptr);
- return ;
- }
复制代码
当向套接字发送3个字节的时候,只读取一个,按道理说epoll应该触发三次,可是这里只触发了一次。
有熟悉的大佬讲一下 
|
|