epoll边缘触发 源代码例子

上传人:鲁** 文档编号:496490904 上传时间:2023-10-06 格式:DOCX 页数:7 大小:11.95KB
返回 下载 相关 举报
epoll边缘触发 源代码例子_第1页
第1页 / 共7页
epoll边缘触发 源代码例子_第2页
第2页 / 共7页
epoll边缘触发 源代码例子_第3页
第3页 / 共7页
epoll边缘触发 源代码例子_第4页
第4页 / 共7页
epoll边缘触发 源代码例子_第5页
第5页 / 共7页
点击查看更多>>
资源描述

《epoll边缘触发 源代码例子》由会员分享,可在线阅读,更多相关《epoll边缘触发 源代码例子(7页珍藏版)》请在金锄头文库上搜索。

1、epoll边缘触发(epoll et)源代码例子在利用epoll编写网络应用程序,特别是服务器的时候。为了得到最优的效果,一般采 用边缘触发(epoll ET)的方式。由于边缘触发,epoll_wait只有在套接字状态发生变化的 时候才会返回。所以要对套接字(socket)进行循环accept,read,write;直到套接字的缓 冲区空(read,accept)或者填满(write)为止。当read返回的字节数小于要读的字节数,或 者返回EAGAIN的时候,认为缓存区为空了。由于网络上已经有很多epollet如何处理 epollin事件的例子,所以下面是本人只提供测试如何处理epollout

2、事件的代码。/*Name: epoll_test.cAuthor :Version:Copyright: Your copyright noticeDescription : epoll et example(echo)此 echo 服务器对输入的内容复制了 REPEAT_NUM(20000次),然后返回给客户端用于测试epollout事件如何触发。*/#include #include #include #include #include #include #include #include #include #include #include #define EPOLL_SIZE 10#d

3、efine EVENT_ARR 20#define BACK_QUEUE 10#define PORT 18001#define BUF_SIZE 16#define REPEAT_NUM 20000#define OUT_BUF_SIZE 32*REPEAT_NUMint g_srv_fd;由于有可能不能一次write所有的内容,所以需要全局变量保存内容的长度,内容输出到那里,在监听到epollout事件后继续上一次的发送char g_out_bufOUT_BUF_SIZE;/保存输出的内容int g_out_buf_offset;/保存输出到那里int g_out_buf_len;保存输出

4、内容的长度int g_has_write_buf;/保存是否要写输出内容void setnonblocking(int sockFd) int opt;opt = fcntl(sockFd, F_GETFL);if (opt 0) printf(fcntl(F_GETFL) fail.);exit(-1);opt |= O_NONBLOCK;if (fcntl(sockFd, F_SETFL, opt) 0 & tmp_len0);if (snd_len = = -1|tmp_len = = -1)& errno = = EAGAIN) | snd_lenbuf_len-offset)fpri

5、ntf(stderr, snd receiv eagin or snd_lenout_lenrn);fprintf(stderr, snd ret:%drn, snd_len);return snd_len;/void process_write(int fd, char *in_buf,int buf_len)char *p_out_buf=g_out_buf;int tmp_offset;int i;for(i = 0; iREPEAT_NUM;i+)tmp_offset+=snprintf(p_out_buf+tmp_offset,OUT_BUF_SIZE-tmp_offset,% d:

6、%srn, i,in_buf);g_out_buf_len =tmp_offset;g_out_buf_offset = 0;g_has_write_buf = 0;g_out_buf_offset +=write_out_buf(fd, g_out_buf, g_out_buf_len,g_out_buf_off set);fprintf(stderr, write_out_buf len:%d wret:%drn, g_out_buf_len, g_out_buf _offset);if (g_out_buf_offsetg_out_buf_len)g_has_write_buf=1; i

7、nt main() int serverFd;serverFd = socket(AF_INET, SOCK_STREAM, 0);g_srv_fd = serverFd;setnonblocking(serverFd);signal(SIGPIPE, SIG_IGN);signal(SIGINT, handle_sig);int epFd = epoll_create(EPOLL_SIZE);struct epoll_event ev, evsEVENT_ARR;ev.data.fd = serverFd;ev.events = EPOLLIN | EPOLLET;epoll_ctl(epF

8、d, EPOLL_CTL_ADD, serverFd, &ev);struct sockaddr_in serverAddr;socklen_t serverLen = sizeof(struct sockaddr_in);serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);serverAddr.sin_port = htons(PORT);if (bind(serverFd, (struct sockaddr *) &serverAddr, serverLen) printf(bind() fail.n);exit(-1);if (listen(se

9、rverFd, BACK_QUEUE) printf(Listen fail.n);exit(-1);int clientFd;struct sockaddr_in clientAddr;socklen_t clientLen;char bufBUF_SIZE;int i = 0;while (1) int nfds = epoll_wait(epFd, evs, EVENT_ARR, -1);for (i = 0; i nfds; i+) if (evsi.data.fd = serverFd & (evsi.events & EPOLLIN) /epollet需要循环对监听的套接字acce

10、pt,直到返回EAGAIN do if (clientFd = accept(serverFd,(struct sockaddr *) &clientAddr, &clientLen) 0); else if (evsi.events & EPOLLIN) fprintf(stderr, epollin event fd:%dn, clientFd);if (clientFd = evsi.data.fd) 0) /epollet需要对套接字循环的读,直到len BUF_SIZE,或者len = 0返回 int len = read(clientFd, buf, BUF_SIZE);fprin

11、tf(stderr, read fd:%d len:%dn, clientFd, len);if (len = BUF_SIZE) do /*if (write(clientFd, buf, len) 0) fprintf(stderr, write fail!n);/break;*/process_write(clientFd, buf, len);if (len BUF_SIZE) fprintf(stderr, len bufsize %d 0);if (len = 0) epoll_ctl(epFd, EPOLL_CTL_DEL, clientFd, &ev);close(clientFd);evsi.data.fd = -1;fprintf(stderr, close fd:%dn, clientFd); else if (len = -1 & errno != EAGAIN) fprintf(stderr, fd:%dn,

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 学术论文 > 其它学术论文

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号