LinuxIO多路复用之poll

来源:互联网 发布:安装阿里云的yum源 编辑:程序博客网 时间:2024/05/21 17:15
#include <sys/types.h>#include <poll.h>#include <sys/socket.h>#include <stdio.h>#include <errno.h>#include <unistd.h>#include <string.h>#include <stdlib.h>#include <arpa/inet.h>#define SERV_PORT 8080#define MAXSIZE 1024#define MAXLINE 64void sys_err(const char *fun_str,int exitno){perror("fun_str");exit(exitno);}int main(){int sockfd, listenfd, connfd;struct sockaddr_in serv_addr,cli_addr;int ret;socklen_t cli_len;int len;int nready;char buf[MAXSIZE];struct pollfd client[MAXSIZE];int i=0,maxi=0;char addr[MAXLINE];listenfd = socket(AF_INET, SOCK_STREAM, 0);if(listenfd<0){sys_err("socket",-1);}bzero(&serv_addr, sizeof(serv_addr));serv_addr.sin_family = AF_INET;serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);serv_addr.sin_port = htons(SERV_PORT);ret = bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));if(ret <0){sys_err("bind",-2);}ret = listen(listenfd,20);if(ret <0 ){sys_err("listen",-3);}client[0].fd = listenfd;client[0].events = POLLIN;for(i=1; i<MAXSIZE; i++){client[i].fd = -1;}printf("accept client connect\n");while(1){nready = poll(client, maxi+1, -1);if(nready <0){sys_err("poll",-4);}//new connectionif(client[0].revents & POLLIN){cli_len = sizeof(cli_addr);connfd = accept(listenfd, (struct sockaddr *)&cli_addr, &cli_len);if(connfd <0){sys_err("accept",-5);}printf("receive from ip %s port %d\n",inet_ntop(connfd, &serv_addr.sin_addr.s_addr, addr, sizeof(addr)), ntohs(serv_addr.sin_port));for(i=1; i<MAXSIZE; i++){if(client[i].fd <0){client[i].fd = connfd;break;}}if(i == MAXSIZE){printf("too many clients\n");exit(0);}client[i].events = POLLIN;if(i >maxi)maxi = i;if(--nready == 0)continue;}for(i=1; i<=maxi; i++){sockfd = client[i].fd;if(sockfd<0)continue;else{len = read(sockfd, buf, sizeof(buf));if(len <0)sys_err("read",-6);else if(0 == len){close(connfd);client[i].fd = -1;printf("client[%d] close\n",i);}else{ret = write(sockfd, buf, len);if(ret<0){sys_err("write",-7);}}}if(--nready == 0)break;}}close(listenfd);return 0;}