poll

来源:互联网 发布:青果教育网络管理系统 编辑:程序博客网 时间:2024/05/22 12:34
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <poll.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/stat.h>#include <arpa/inet.h>#include <netinet/in.h>#include <string.h>#define POLLFD_SIZE 1024//一个 对文件描述符事件struct pollfd array_pollfd[POLLFD_SIZE];/* 结构体成员详情 struct pollfd  {     int fd;        // 关心的描述符     short events;  // 关心的事件     short revents; // 发生的事件 }; *//*获取一个监听的socket*/int get_listen(char *ip, short port){    int sock = socket(AF_INET,SOCK_STREAM,0);    if(sock <0)    {        perror("socket");        exit(2);    }    int opt =1;    setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));    struct sockaddr_in local;    local.sin_family = AF_INET;    local.sin_port = htons(port);    local.sin_addr.s_addr =inet_addr(ip);    //bind    if(bind(sock,(struct sockaddr*)&local,sizeof(local)) < 0)    {        perror("bind");        exit(3);    }    //listen    if(listen(sock,10)<0)    {        perror("listen");        exit(4);    }    return sock;}/*运行poll_server服务器*/void poll_server(int listen_sock){    /*将负责的监听的sock注册*/    array_pollfd[0].fd = listen_sock;    array_pollfd[0].events = POLLIN;    int idx = 1;    for(;idx < POLLFD_SIZE; ++idx)        array_pollfd[idx].fd= -1;    int timeout = 1000;/*1000毫秒*/    while(1)    {        int res = poll(array_pollfd,POLLFD_SIZE,timeout);        if(res == 0)            printf("timeout\n");        else if(res < 0)            perror("poll");        else         {            //有关心的事件已就绪            int index = 0;            for(;index < POLLFD_SIZE;++index)            {                if(index == 0 && array_pollfd[0].revents & POLLIN)                {                    //listen_sock 读事件就绪,响应accpet                    struct sockaddr_in cliaddr;                    socklen_t len = sizeof(cliaddr);                    int new_sock = accept(listen_sock,(struct sockaddr*)&cliaddr,&len);                    if(new_sock < 0)                    {                        perror("accept");                        continue;                    }                    else                     {                        printf("get a client:%s, %d\n",\                        inet_ntoa(cliaddr.sin_addr),ntohs(cliaddr.sin_port));                        //将新的sock添加到数组中                        int k = 1;                        for(;k < POLLFD_SIZE;++k)                        {                            if(array_pollfd[k].fd < 0)                            {                                array_pollfd[k].fd = new_sock;                                //将新的sock关注读事件                                array_pollfd[k].events = POLLIN;                                break;                            }                        }                        //表示没有可用的文件接口                        if(k == POLLFD_SIZE)                        {                            close(new_sock);                            return ;                        }                    }                }                else if(index != 0 && array_pollfd[index].revents & POLLIN)                {                    //其他文件描述符读事件就绪                    char buf[1024];                    memset(buf,0,1024);                    ssize_t s = read(array_pollfd[index].fd,buf,sizeof(buf)-1);                    if(s > 0)                    {                        buf[s] = 0;                        printf("client say#:%s\n",buf);                        array_pollfd[index].events = POLLOUT;                    }                    else if(s <= 0)                    {                        printf("client quit\n");                                                close(array_pollfd[index].fd);                        //必须修改文件描述符为初始状态,                        array_pollfd[index].fd = -1;                    }                }                else if(index != 0 && array_pollfd[index].revents & POLLOUT)                {                    //其他文件描述符写事件就绪                    const char* msg = "HTTP/1.1 200 OK\r\n\r\n<html><br/><h1>Hello poll!</h1></html>";                      write(array_pollfd[index].fd,msg,strlen(msg));                    close(array_pollfd[index].fd);                    array_pollfd[index].fd = -1;                }            }        }    }}int main(int argc, char* argv[]){    if(argc != 3)    {        printf("Usge:%s [ip] [port]\n",argv[0]);        return 1;    }    int listen_sock = get_listen(argv[1],atoi(argv[2]));    poll_server(listen_sock);    return 0;}
原创粉丝点击