linux 下 poll 编程
poll 与 select 很类似,都是对描述符进行遍历,查看是否有描述符就绪。如果有就返回就绪文件描述符的个数将。poll 函数如下:
#include <poll.h>
int poll(struct pollfd *fdarray, unsigned long nfds, int timeout)
第一个参数指向结构数组第一个元素的指针,每个数组都是一个 pollfd 结构iouyonghu制定额是某个给定描述符的条件。
struct pollfd
{
int fd;
short events;//关心 fd 上发生的事件
short revents;//fd 实际上上发生的事件
}
第二个参数 nfds 制定数组中元素个数。第三个参数指定 poll 函数返回前等待多长时间。 INFTIM 表示永远等待, 0 代表立即返回, > 0 等待指定数目的秒数。
poll 编程实例,这是 TCP 连接服务器端代码:
1 #include <sys/socket.h> 2 #include <netinet/in.h> 3 #include <stdio.h> 4 #include <error.h> 5 #include <errno.h> 6 #include <unistd.h> 7 #include <string.h> 8 #include <stdlib.h> 9 #include <sys/wait.h> 10 #include <limits.h> 11 #include <poll.h> 12 #include <sys/stropts.h> 13 #include <signal.h> 14 #define MAXLINE 5 15 #define OPEN_MAX 1024 16 #define SA struct sockaddr 17 18 19 int main() 20 { 21 int listenfd, connfd, sockfd, i, maxi; 22 int nready; 23 socklen_t clilen; 24 ssize_t n; 25 char buf[MAXLINE]; 26 struct pollfd client[OPEN_MAX]; 27 struct sockaddr_in servaddr, cliaddr; 28 //创建监听套接字 29 if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) 30 { 31 printf("socket() error!"); 32 exit(0); 33 } 34 //先要对协议地址进行清零 35 bzero(&servaddr,sizeof(servaddr)); 36 //设置为 IPv4 or IPv6 37 servaddr.sin_family = AF_INET; 38 //绑定本地端口号 39 servaddr.sin_port = htons(9805); 40 //任何一个 IP 地址,让内核自行选择 41 servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 42 //绑定套接口到本地协议地址 43 if(bind(listenfd, (SA *) &servaddr,sizeof(servaddr)) < 0) 44 { 45 printf("bind() error!"); 46 exit(0); 47 } 48 //服务器开始监听 49 if(listen(listenfd,5) < 0) 50 { 51 printf("listen() error!"); 52 exit(0); 53 } 54 client[0].fd = listenfd; 55 client[0].events = POLLRDNORM;//关心监听套机字的读事件 56 for(i = 1; i < OPEN_MAX; ++i) 57 { 58 client[i].fd = -1; 59 } 60 maxi = 0; 61 for(;;) 62 { 63 nready = poll(client, maxi + 1, -1); 64 if(client[0].revents & POLLRDNORM) 65 { 66 clilen = sizeof(cliaddr); 67 //accept 的后面两个参数都是值-结果参数,他们的保留的远程连接电脑的信息,如果不管新远程连接电脑的信息,可以将这两个参数设置为 NULL 68 connfd = accept(listenfd, (SA *) &cliaddr, &clilen); 69 if(connfd < 0) 70 { 71 continue; 72 } 73 for(i = 1; i < OPEN_MAX; ++i) 74 { 75 if(client[i].fd < 0) 76 client[i].fd = connfd; 77 break; 78 } 79 if(i == OPEN_MAX) 80 { 81 printf("too many clients"); 82 exit(0); 83 } 84 client[i].events = POLLRDNORM; 85 if(i > maxi) 86 { 87 maxi = i; 88 } 89 if(--nready <=0 ) 90 continue; 91 } 92 for(i = 1; i < OPEN_MAX; ++i) 93 { 94 if((sockfd = client[i].fd) < 0) 95 { 96 continue; 97 } 98 if(client[i].revents & POLLRDNORM | POLLERR) 99 { 100 if((n = read(sockfd, buf, MAXLINE)) < 0) 101 { 102 if(errno == ECONNRESET) 103 { 104 close(sockfd); 105 client[i].fd = -1; 106 } 107 else 108 { 109 printf("read error!\n"); 110 } 111 } 112 else if(n == 0) 113 { 114 close(sockfd); 115 client[i].fd = -1; 116 } 117 else 118 { 119 write(sockfd, buf, n); 120 } 121 if(--nready <= 0) 122 break; 123 } 124 } 125 } 126 }
配合 linux 下 select 编程 就是一个完整的客户端/服务器端代码了,运行结果截图如下:
客户端:
服务器端:
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。