千家信息网

I/O多路转接   ----   poll

发表于:2025-12-02 作者:千家信息网编辑
千家信息网最后更新 2025年12月02日,一、pollpoll的实现和select非常相似,只是描述fd集合的方式不同,poll使用pollfd结构而不是select的fd_set结构,其他的都差不多。二、poll相关函数#include i
千家信息网最后更新 2025年12月02日I/O多路转接   ----   poll

一、poll

poll的实现和select非常相似,只是描述fd集合的方式不同,poll使用pollfd结构而不是select的fd_set结构,其他的都差不多


二、poll相关函数

#include

int poll(struct pollfd *fds, nfds_t nfds, int timeout);

//fds: pollfd结构体

events: 要监视的事件

revents: 已经发生的事件, 设置标志 来反映相关条件的存在

常量 说明

POLLIN 普通或优先级带数据可读

POLLRDNORM 普通数据可读

POLLRDBAND 优先级带数据可读

POLLPRI 高优先级数据可读

POLLOUT 普通数据可写

POLLWRNORM 普通数据可写

POLLWRBAND 优先级带数据可写


// 只能作为描述字的返回结果存储在revents中

POLLERR 发生错误

POLLHUP 发生挂起

POLLNVAL 描述字不是一个打开的文件

struct pollfd {    int   fd;         /* 文件描述符 */      short events;     /* 请求的事件 */        short revents;    /* 返回的事件 */  };

//nfds: 要监视的描述符的数目

//timeout:指定poll在返回前没有接收事件时应该等待的时间【单位:ms】。

INFTIM: 永不超时

0 :立即返回

>0: 等待指定的时间

2、特点:

pollfd并没有最大数量限制(但是数量过大后性能也是会下降)。

和select函数一样,poll返回后,需要轮询pollfd来获取就绪的描述符。

select和poll都需要在返回后,通过遍历文件描述符来获取已经就绪的socket。事实上,同时连接的大量客户端在一时刻可能只有很少的处于就绪状态,因此随着监视的描述符数量的增长,其效率也会线性下降。

三、poll 服务器

#include #include#include#include#include#include#include#include#include#include#include#define _BACKLOG_ 5#define _MAX_NUM_ 64void usage(const char *proc){        printf("Usage: %s [ip][port]\n",proc);}static int startup(const char *ip,const int port){        int sock=socket(AF_INET,SOCK_STREAM,0);        if(sock < 0)        {                perror("socket");                exit(1);        }        int opt=1;        setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));        struct sockaddr_in local;        local.sin_family=AF_INET;        local.sin_port=htons(port);        local.sin_addr.s_addr=inet_addr(ip);                if(bind(sock,(struct sockaddr*)&local,sizeof(local)) < 0)        {                perror("bind");                exit(2);        }               if(listen(sock,_BACKLOG_) < 0)        {                perror("listen");                               exit(3);        }        return sock;}static int poll_server(int listen_sock){        struct sockaddr_in client;        socklen_t len=sizeof(client);                struct pollfd fds[_MAX_NUM_];        fds[0].fd=listen_sock;        fds[0].events=POLLIN;        fds[0].revents=0;        size_t i=0;        for(;i<_MAX_NUM_;++i)        {                fds[i].fd=-1;                fds[i].events=0;                fds[i].revents=0;        }        int max_fd=1;        int timeout=5000;        while(1)        {                switch(poll(fds,max_fd,timeout))                {                case -1://error                        perror("poll");                        break;                case 0://timeout                        printf("poll timeout");                        break;                default://normal                         {                                for(i=0;i<_MAX_NUM_;++i)                                {                                        //is listen events ready?                                        if(fds[i].fd == listen_sock && fds[i].revents == POLLIN)                                        {                                                int accept_sock=accept(listen_sock,(struct sockaddr*)&client,&len);                                                if(accept_sock < 0)                                                {                                                        perror("accept");                                                        continue;                                                }                                                printf("get a client...[ip: %s][port: %d]\n",\                                                                inet_ntoa(client.sin_addr),ntohs(client.sin_port));                                                for(i=0;i<_MAX_NUM_;++i)                                                {                                                        if(fds[i].fd == -1)                                                        {                                                                fds[i].fd=accept_sock;                                                                fds[i].events=POLLIN;                                                                max_fd++;                                                                break;                                                        }                                                }                                                if(i == _MAX_NUM_)                                                {                                                        close(accept_sock);                                                }                                        }                                        else if(fds[i].fd > 0 && fds[i].revents == POLLIN)                                        {                                                char buf[1024];                                                ssize_t _size=read(fds[i].fd,buf,sizeof(buf)-1);                                                if(_size > 0)//read success                                                {                                                        buf[_size]='\0';                                                        printf("Client # %s",buf);                                                }                                                else if(_size == 0)//client close                                                {                                                        printf("clint close...\n");                                                        struct pollfd tmp=fds[i];                                                        fds[i]=fds[max_fd-1];                                                        close(fds[max_fd-1].fd);                                                        fds[max_fd-1].fd=-1;                                                        fds[max_fd-1].events=0;                                                        fds[max_fd-1].revents=0;                                                        --max_fd;                                                }                                        }                                        else                                        {}                                }                        }                        break;                }        }        return 0;}int main(int argc,char *argv[]){        if(argc != 3)        {                usage(argv[0]);                return 1;        }        char *ip=argv[1];        int port=atoi(argv[2]);        int listen_sock=startup(ip,port);        poll_server(listen_sock);        close(listen_sock);        return 0;}

总结:

poll在返回后,需要通过遍历文件描述符来获取已经就绪的socket从而进行下一步操作;而且使用完监听套接字后,都需要进行关闭。


数据 事件 普通 优先级 文件 数量 结构 监视 函数 时间 不同 最大 相似 差不多 事实 事实上 单位 只是 只有 同时 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 服务器连接到移动硬盘 数据库数据量超大如何解决 数据库中的主键有哪几个特性 英雄联盟游戏匹配数据库 梦幻西游手游最鬼的服务器 黄浦区品牌软件开发服务保障 数据库的完整性保护实验总结 世上真的有网络安全大赛吗 智能照明软件开发中心 贺州网络安全宣传 计算机网络技术所需职业性格类型 魔兽世界角色服务器无法连接 中国电信网络安全工程师工资 网络安全ptt课件 网络安全个人学习心得1000字 腐蚀 服务器管理工具 惠州专业软件开发 计算机网络技术大一数学课本 mc动画菜鸟vs大神服务器 上海宜寻网络技术有限公司 余姚嵌入式软件开发商 酒店软件开发系统 中医糖尿病防治数据库 守睿软件开发服 专科选会计还是网络技术 安庆工程管理软件开发哪家好 vps测试配置vps服务器 望江网络安全排名 csmar数据库 ABC 计算机三级网络技术考试成绩
0