多路转接模型之poll
来源:互联网 发布:水果音乐软件下载 编辑:程序博客网 时间:2024/06/05 18:31
poll系统调用和select类似,也是在指定时间内轮询一定数量的文件描述符,以测试其中是否有就绪者。poll和select效率差不多,只是其使用接口相对简单些,poll不在局限于1024个文件描述符,poll监听事件和触发事件分开,event表示监听事件,revents表示触发的事件。相比select不用每一次都需要重新设置监听事件。
#include <poll.h> int poll(struct pollfd *fds, nfds_t nfds, int timeout);//第一个参数是struct pollfd数组struct pollfd { int fd; /* file descriptor */你要监控文件描述符 short events; /* requested events */ 监听文件描述符上的事件 传入参数由用户设置 short revents; /* returned events */监控文件描述符事件返回值 传出参数由内核设置};POLLIN普通或带外优先数据可读,即POLLRDNORM | POLLRDBANDPOLLRDNORM-数据可读POLLRDBAND-优先级带数据可读POLLPRI 高优先级可读数据POLLOUT普通或带外数据可写POLLWRNORM-数据可写POLLWRBAND-优先级带数据可写POLLERR 发生错误POLLHUP 发生挂起POLLNVAL 描述字不是一个打开的文件第二个参数,指结构体数组长度。timeout 毫秒级等待-1:阻塞等,#define INFTIM -1 Linux中没有定义此宏0:立即返回,不阻塞进程>0:等待指定毫秒数,如当前系统时间精度不够毫秒,向上取值poll server端实例:
#include<stdio.h>#include<string.h>#include<poll.h>#include <sys/un.h>#include <sys/types.h> #include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include<errno.h>#define OPEN_MAX 1024int create_listen(int port){int listen_st,on;struct sockaddr_in s_addr;listen_st =socket(AF_INET,SOCK_STREAM,0);if(listen_st==-1){perror("socket error ");return -1;}if(setsockopt(listen_st,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))==-1){perror("setsockopt error");return -1;}s_addr.sin_port=htons(port);s_addr.sin_family=AF_INET;s_addr.sin_addr.s_addr=htonl(INADDR_ANY);if(bind(listen_st,(struct sockaddr*)&s_addr,sizeof(struct sockaddr_in))==-1){perror("bind error");return -1;}if (listen(listen_st, 5) == -1) // 设置文件描述符具有监听的功能 { perror("listen error"); return -1; } return listen_st; }int run_server(int port){int i,maxi,listen_st,conn_st,sockaddr_len;int nready;struct pollfd client[OPEN_MAX];char buf[1024];struct sockaddr_in c_addr;listen_st=create_listen(port);if(listen_st==-1){return -1;}for(i=1;i<OPEN_MAX;i++){client[i].fd=-1;}client[0].fd=listen_st;client[0].events=POLLIN;maxi=0;while(1){nready = poll(client,maxi+1,-1);//poll 阻塞if(nready<0){perror("poll error");break;}if((client[0].revents&POLLIN))//检测listen_st {sockaddr_len=sizeof(c_addr);conn_st=accept(listen_st,(struct sockaddr *)&c_addr,&sockaddr_len);printf("received form %s at port:%d \n",inet_ntoa(c_addr.sin_addr),ntohs(c_addr.sin_port));for(i=0;i<OPEN_MAX;i++){if(client[i].fd<0){client[i].fd=conn_st;client[i].events=POLLIN;break;}}if(i==OPEN_MAX){printf("too many client \n");close(conn_st);}else{if(i>maxi) //记录最大下标{maxi=i;}}if(--nready==0) continue;}for(i=1;i<=maxi;i++){if((conn_st=client[i].fd)<0){continue;}if(client[i].revents&POLLIN){memset(buf,0,sizeof(buf));int rv=read(conn_st,buf,sizeof(buf));if(rv<0){if(errno==ECONNRESET)/* 当收到RST标志时*/ //这种错误是由于客户端发过FIN ACk掉线了客服端进程已经结束了 服务端再发FIN 客户端会发送RST{printf("client aborted connection \n");close(conn_st);client[i].fd=-1;}}else if(rv==0){printf("close client \n");close(conn_st);client[i].fd=-1;}else{printf("recv from client:%s \n",buf);write(conn_st,buf,strlen(buf));}if (--nready == 0) break; //就绪个数减一}}}close(listen_st);return 0;}int main(int argc,char *argv[]){if(argc<2){printf("usage:%s port \n",argv[0]);return 0;}int port=atoi(argv[1]);if(port==0){printf("port error \n");return 0;}printf("start server \n");run_server(port);return 0;}
0 0
- 多路转接模型之poll
- I/O多路转接之poll
- I/O多路转接之poll
- I/O多路转接之poll
- I/O多路转接之poll
- I/O多路转接之poll
- I/O多路转接之poll
- I/O多路转接之poll
- I/O多路转接之poll
- I/O多路转接之poll
- 多路转接服务器之poll
- Linux I/O多路转接----poll模型
- I/O多路转接之select、poll、epoll
- I/O多路转接之poll 函数
- 【计算机网络】I/O多路转接之poll
- I/O多路转接之poll服务器
- IO多路转接之select、poll、epoll
- Linux—I/O多路转接之poll
- 让eclipse validating变快
- 白城代开医院住院出院证明
- 蛟河代开医院住院出院证明
- 大安代开医院住院出院证明
- 双辽代开医院住院出院证明
- 多路转接模型之poll
- 图们代开医院住院出院证明
- 敦化代开医院住院出院证明
- 和龙代开医院住院出院证明
- 南昌代开医院住院出院证明
- hadoop学习笔记之HiveSQL 数据查询
- 吉安代开医院住院出院证明
- hive cli启动报错
- Programming Is an Act of Design