多路复用I/O模型poll() 模型 代码实现
poll()机制和select()机制是相似的,都是对多个描述符进行轮询的方式。
不同的是poll()没有描述符数目的限制。
是通过struct pollfd结构体,对每个描述符进行轮询的
struct pollfd fdarray
{
int fd; /*文件描述符*/
short events; /*表示等待的事件*/
short revents;/*表示返回事件即实际发生的事件*/
};
data.h
#ifndef DATA_H #define DATA_H #include <string.h> #include <stdio.h> #include <poll.h> #include <sys/types.h> #include <sys/stat.h> #include <stdlib.h> #include <errno.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/select.h> #include <arpa/inet.h> #include <assert.h> #include <unistd.h> #define maxn 1100 #define MAXLINE 10 #define LISTEN 10 #define IP "127.0.0.1" #define PORT 4578 #define BACKLOG 5 #define INFTIM -1 #endif
server.c
1 #include "data.h" 2 static void deal_message(struct pollfd *fd_array,int num); 3 static void poll_accept(int sockfd); 4 5 static int init() 6 { 7 struct sockaddr_in server_in; 8 int sockfd; 9 if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1) 10 { 11 fprintf(stderr,"socket fail,error :%s\n",strerror(errno)); 12 return -1; 13 } 14 bzero(&server_in,sizeof(server_in)); 15 server_in.sin_family = AF_INET; 16 server_in.sin_port = htons(PORT); 17 inet_pton(AF_INET,IP,&server_in.sin_addr); 18 if(bind(sockfd,(struct sockaddr*)&server_in,sizeof(struct sockaddr)) == -1) 19 { 20 fprintf(stderr,"bind fail,error:%s\n",strerror(errno)); 21 return -1; 22 } 23 listen(sockfd,BACKLOG); 24 return sockfd; 25 } 26 27 static void poll_accept(int sockfd) 28 { 29 struct pollfd fd_array[maxn]; 30 int afd; 31 int pollfd; 32 struct sockaddr_in client_in; 33 bzero(&client_in,sizeof(client_in)); 34 int i = 0; 35 fd_array[0].fd = sockfd; 36 fd_array[0].events = POLLIN; 37 for(i=0;i<maxn;i++) 38 { 39 fd_array[i].fd = -1; 40 } 41 int num = 0; 42 int len = sizeof(client_in); 43 while(1) 44 { 45 46 pollfd = poll(fd_array,num+1,INFTIM); 47 if(pollfd == -1) 48 { 49 fprintf(stderr,"poll fail,error %s\n",strerror(errno)); 50 return; 51 } 52 if(pollfd == 0) 53 { 54 continue; 55 } 56 if(fd_array[0].revents & POLLOUT) 57 { 58 if((afd = accept(sockfd,(struct sockaddr*)&client_in,&len)) == -1) 59 { 60 fprintf(stderr,"accept fail,error:%s\n",strerror(errno)); 61 return ; 62 } 63 } 64 i = 0; 65 for(i =0;i<maxn;i++) 66 { 67 if(fd_array[i].fd < 0) 68 { 69 fd_array[i].fd = afd; 70 break; 71 } 72 } 73 if(i == maxn) 74 { 75 printf("too many to server!\n"); 76 return ; 77 } 78 fd_array[i].events = POLLIN; 79 if(i > num ) 80 num = i; 81 if(--pollfd <= 0) 82 continue; 83 } 84 deal_message(fd_array,num); 85 } 86 87 static void deal_message(struct pollfd *fd_array,int num) 88 { 89 int i,n; 90 char buf[maxn]; 91 memset(buf,‘\0‘,sizeof(buf)); 92 for(i=1;i<=num;i++) 93 { 94 if(fd_array[i].fd < 0) 95 continue; 96 if(fd_array[i].revents&POLLIN) 97 { 98 n = read(fd_array[i].fd,buf,maxn); 99 if(n == 0) 100 { 101 close(fd_array[i].fd); 102 fd_array[i].fd = -1; 103 continue; 104 } 105 write(STDOUT_FILENO,buf,n); 106 write(fd_array[i].fd,buf,n); 107 } 108 } 109 } 110 int main() 111 { 112 int sockfd = init(); 113 poll_accept(sockfd); 114 close(sockfd); 115 return 0; 116 }
时间: 2024-10-24 20:08:40