对于非阻塞socket的可写事件

来源:互联网 发布:完美假期周晨曦淘宝店 编辑:程序博客网 时间:2024/06/05 14:20

当socket设置成非阻塞时,并且将EPOLLOUT事件通过epoll_ctl添加时,可写事件总是会触发,可以通过写代码来验证

代码如下:

#include <sys/socket.h>#include <sys/epoll.h>#include <unistd.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdlib.h>#include <fcntl.h>#include <string.h>#include <stdio.h>#define SERV_PORT  10000#define MAX_EVENTS 10#define LEN 2int main(int argc, char **argv){if (argc != 2) {perror("usage:exe port\n");return -1;}struct sockaddr_in servaddr;int sockfd;memset(&servaddr, 0x00, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_port = htons(atoi(argv[1]));servaddr.sin_addr.s_addr = htonl(INADDR_ANY);sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0) {perror("socket error");exit(-1);}if (bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1) {perror("bind error");close(sockfd);exit(-1);}if (listen(sockfd, 3) == -1) {perror("listen error");close(sockfd);exit(-1);}int epollfd = epoll_create(MAX_EVENTS);if (epollfd == -1) {perror("epoll_create error");close(sockfd);exit(-1);}struct epoll_event ev, events[MAX_EVENTS];ev.events = EPOLLIN;ev.data.fd = sockfd;if (epoll_ctl(epollfd, EPOLL_CTL_ADD, sockfd, &ev) == -1) {perror("epoll_ctl error");exit(-1);}int nfds, connfd;for (;;) {nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);if (nfds == -1) {perror("epoll_wait error");exit(-1);}int i;for (i = 0; i < nfds; i++) {if (events[i].data.fd == sockfd) {connfd = accept(sockfd, NULL, NULL);printf("connfd=%d\n", connfd);if (connfd == -1) {perror("accept error");exit(-1);}int flag;flag = fcntl(connfd, F_GETFL, 0);fcntl(connfd, F_SETFL, flag & ~O_NONBLOCK);ev.events = EPOLLOUT;ev.data.fd = connfd;if (epoll_ctl(epollfd, EPOLL_CTL_ADD, connfd, &ev) == -1) {perror("epoll_ctl error");exit(-1);}} else {/*char buf[LEN];int n = read(events[i].data.fd, buf, LEN);buf[n] = 0;printf("buf=%s\n", buf);*/if (events[i].events & EPOLLOUT) {printf("fd=%d\n", events[i].data.fd);}}}}}

当监听到有连接到来时,接收连接,并且将连接设置成非阻塞,添加EPOLLOUT事件,这时会一直打印fd=5

输出为


可以像libevent那样,当有数据要写时,才将描述符fd添加进去,数据写完之后,再将fd删除

0 0