博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poll 示例
阅读量:5807 次
发布时间:2019-06-18

本文共 2507 字,大约阅读时间需要 8 分钟。

hot3.png

poll 使用的结构体如下

struct pollfd {    int   fd;         /* file descriptor */    short events;     /* requested events */    short revents;    /* returned events */};

需要使用该结构体数组对文件描述符进行注册,poll 通过该数组返回结果。事件就绪时需要遍历所有注册的文件描述符。

源码

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#define SERV_PORT 9000#define LISTENQ 10#define OPEN_MAX 1024#define MAXLINE 1024int main(int argc, char **argv){ int listenfd, connfd, sockfd; int nready, maxi, i, n; socklen_t clilen; struct sockaddr_in cliaddr, servaddr; struct pollfd client[OPEN_MAX]; char buf[MAXLINE]; /* 创建 socket */ if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(EXIT_FAILURE); } memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SERV_PORT); /* 绑定地址到 socket */ if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) { perror("bind"); exit(EXIT_FAILURE); } /* 转为监听 socket */ if (listen(listenfd, LISTENQ)) { perror("listen"); exit(EXIT_FAILURE); } client[0].fd = listenfd; client[0].events = POLLRDNORM; for (i = 1; i < OPEN_MAX; ++i) { client[i].fd = -1; } maxi = 0; for ( ; ; ) { nready = poll(client, maxi + 1, 1000); if (nready < 0) { perror("poll"); exit(EXIT_FAILURE); } else if (nready == 0) { fprintf(stderr, "timeout\n"); } if (client[0].revents & POLLRDNORM) { /* 监听 socket 上读事件 */ clilen = sizeof(cliaddr); connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen); if (connfd == -1) { perror("accept"); continue; } fprintf(stderr, "accept %d\n", connfd); /* 从client 数组中找到一个空位 */ for (i = 1; i < OPEN_MAX; i++) { if (client[i].fd < 0) { client[i].fd = connfd; break; } } if (i == OPEN_MAX) { fprintf(stderr, "too many clients"); exit(EXIT_FAILURE); } client[i].events = POLLRDNORM; if (i > maxi) { maxi = i; } if (--nready <= 0) { continue; } } /* 剩余的文件描述符 */ for (i = 1; i <= maxi; ++i) { if ((sockfd = client[i].fd) < 0) continue; if (client[i].revents & (POLLRDNORM | POLLERR)) { /* 读事件 */ if ((n = read(sockfd, buf, MAXLINE)) < 0) { if (errno == ECONNRESET) { close(sockfd); client[i].fd = -1; } else { fprintf(stderr, "read error"); } } else if (n == 0) { /* 客户端关闭连接 */ close(sockfd); client[i].fd = -1; } else { /* 回写数据到客户端 */ write(sockfd, buf, n); } if (--nready <= 0) { break; } } } } return 0;}

参考资料

《UNP》

转载于:https://my.oschina.net/lowkey2046/blog/705915

你可能感兴趣的文章
采用JXL包进行EXCEL数据写入操作
查看>>
***CodeIgniter框架集成支付宝即时到账支付SDK
查看>>
Struts2访问ServletAPI的三种方式
查看>>
一周总结
查看>>
将txt文件转化为json进行操作
查看>>
XML
查看>>
【我的总结20170823】多实例部署
查看>>
[MySQL优化案例]系列 — slave延迟很大优化方法
查看>>
线性表4 - 数据结构和算法09
查看>>
C语言数据类型char
查看>>
Python线程详解
查看>>
Online Patching--EBS R12.2最大的改进
查看>>
说说我的web前端之路,分享些前端的好书
查看>>
Binary Search Tree Iterator leetcode
查看>>
Oracle性能优化--DBMS_PROFILER
查看>>
关闭Jquery Ajax 缓存
查看>>
uva-317-找规律
查看>>
Event事件的兼容性(转)
查看>>
CQRS学习——一个例子(其六)
查看>>
Hadoop 学习资料集锦
查看>>