poll函数

来源:互联网 发布:软件需求变更申请表 编辑:程序博客网 时间:2024/06/01 08:13
//TCP回射服务器poll实现#include<stdio.h>//#include<stdlib.h>#include<sys/types.h>//#include<sys/stat.h>#include<sys/socket.h>#include<poll.h>#include<netinet/in.h>#include<unistd.h>#include<strings.h>#include<string.h>#include<limits.h>#include<errno.h>#include<stdlib.h>#include<stropts.h>//INFTIM包含的文件#define LISTENQ 1024#define OPEN_MAX 1024#define MAXLINE 4096int main(void){    int listenfd, connfd, sockfd;//监听套接字、已连接的套接字    struct sockaddr_in server_sockaddr, client_sockaddr;//套接字地址结构    struct pollfd client[OPEN_MAX];//客户信息    socklen_t clilen;    int i, maxi, nready, n;    char buf[MAXLINE];    if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)//创建一个套接字    {        fprintf(stderr, "Socket failed\n");        exit(EXIT_FAILURE);    }    else    printf("Socket success\n");    bzero(&server_sockaddr, sizeof(server_sockaddr));    server_sockaddr.sin_family = AF_INET;//TCP/IP协议族    server_sockaddr.sin_port = htons(9877);//以网络字节序存储端口    server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);//以网络字节序存储IP地址    if(bind(listenfd, (struct sockaddr*)&server_sockaddr, sizeof(server_sockaddr)) < 0)    {        fprintf(stderr, "Bind failed\n");//stderr不带缓冲,速度快        exit(EXIT_FAILURE);    }    else        printf("Bind success\n");    if(listen(listenfd, LISTENQ) < 0)    {        fprintf(stderr, "Listen failed\n");        exit(EXIT_FAILURE);    }    else        printf("Listen success\n");    client[0].fd = listenfd;//给监听描述符加入client数组中    client[0].events = POLLRDNORM;    for(i=1; i<OPEN_MAX; i++)        client[i].fd = -1;//数组中其他描述符初始化为-1    maxi = 0;//存储索引最大值    memset(buf, 0, MAXLINE);    while(1)    {        nready = poll(client, maxi+1, -1);//poll函数        if(client[0].revents & POLLRDNORM)//new client connection        {            clilen = sizeof(client_sockaddr);            connfd = accept(listenfd, (struct sockaddr*)&client_sockaddr, &clilen);//连接新的客户            for(i=1; i<OPEN_MAX; i++)            {                if(client[i].fd < 0)//将新的已连接的描述符加入client数组                {                    client[i].fd = connfd;                    break;                }            }            //client[i].events = POLLRDNORM;            if(i == OPEN_MAX)            {                fprintf(stderr, "too many clients\n");                exit(EXIT_FAILURE);            }            client[i].events = POLLRDNORM;            if(i > maxi)                maxi = i;            if(--nready <= 0)                continue;//no more readable descriptors        }        //处理已经连接的客户        for(i=1; i<= maxi; i++)        {            if((sockfd = client[i].fd) < 0)                continue;            if(client[i].revents & (POLLRDNORM | POLLERR))            {                if((n = read(sockfd, buf, MAXLINE)) < 0)                {                    if(errno == ECONNRESET)                    {                        close(sockfd);//终止连接                        client[i].fd = -1;                    }                    else                        exit(EXIT_FAILURE);                }                else if(n == 0)//connection closed by client                {                    close(sockfd);                    client[i].fd = -1;                }                else                {                    printf("%s\n", buf);                    write(sockfd, buf, n);                    memset(buf, 0, MAXLINE);                }                if(--nready <= 0)//no more readable descriptors                    break;            }        }    }   }
原创粉丝点击