zoukankan      html  css  js  c++  java
  • linux poll

    man poll:

    NAME
    poll, ppoll - wait for some event on a file descriptor

    SYNOPSIS
    #include <poll.h>

    int poll(struct pollfd *fds, nfds_t nfds, int timeout);

    #define _GNU_SOURCE /* See feature_test_macros(7) */
    #include <poll.h>

    int ppoll(struct pollfd *fds, nfds_t nfds,
    const struct timespec *timeout_ts, const sigset_t *sigmask);

    DESCRIPTION
    poll() performs a similar task to select(2): it waits for one of a set of file descriptors to become ready to per‐
    form I/O.

    The set of file descriptors to be monitored is specified in the fds argument, which is an array of structures of the
    following form:

    struct pollfd {
    int fd; /* file descriptor */
    short events; /* requested events */
    short revents; /* returned events */
    };

    测试的条件由events指定,函数在相应的revents成员中返回该描述字的状态。(每个描述字都有两个变量,一个为调用值,另一个为返回结果,从而避免使用值结果参数。)

    结果数组中元素的个数由nfds参数指定。

    返回值:当发生错误时,poll函数的返回值为-1,若定时器时间到之前没有任何描述字就绪,则返回0.否则返回就绪描述字的个数,即其revents成员值非0的描述字个数。

    如果我们不再关心某个特定描述字,那么可以把与它对应的pollfd结构的fd成员设置为一个负值。poll函数将忽略这样的pollfd结构的events成员,返回时将它的revents成员的值置为0.

      020.#ifndef INFTIM     /*按照书上解释:POSIX规范要求INFTIM在头文件<poll.h>中定义,不过*/

      021.#define INFTIM -1  /*许多系统仍然把它定义在头文件<sys/stropts.h>中,但是经过我的测试*/

      022.#endif             /*即使都包含这两个文件,编译器也找不到,不知何解。索性自己定义了。*/

     

    #include"unp.h"
    #include<limits.h>//for open_MAX,ubuntuۃбûԐ
    #define OPEN_MAX 1024
    #define INFTIM -1
    
    int main(int argc,char **argv)
    {
        int i ,maxi,listenfd,connfd,sockfd;
        int nready;
        ssize_t n;
        
        socklen_t clilen;
        char buf[MAXLINE];
        
        struct pollfd client[OPEN_MAX];
        struct sockaddr_in cliaddr,servaddr;
        listenfd=Socket(AF_INET,SOCK_STREAM,0);
        bzero(&servaddr,sizeof(servaddr));
        servaddr.sin_family=AF_INET;
        servaddr.sin_port=htons(8001);
        servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
        
        Bind(listenfd,(SA*)&servaddr,sizeof(servaddr));
        Listen(listenfd,LISTENQ);
        
        client[0].fd=listenfd;
        client[0].events=POLLRDNORM;
        for(i=1;i<OPEN_MAX;i++)
            client[i].fd=-1;// 
        maxi=0;
        
        for(;;)
        {
            nready=poll(client,maxi+1,INFTIM);
            if(client[0].revents  & POLLRDNORM ) 
            { //new client connction
                clilen=sizeof(cliaddr);
                connfd=Accept(listenfd,(SA*)&cliaddr,&clilen);
                
                for(i=1;i<OPEN_MAX;i++)
                {
                    if(client[i].fd<0)
                    {
                        client[i].fd=connfd;//save desc
                        break;
                    }
                }
                if(i==OPEN_MAX)
                    err_quit("too many client");
                client[i].events=POLLRDNORM;
                if(i>maxi)
                    maxi=i;
                if(--nready<=0)
                    continue;
            }
            for(i=1;i<=maxi;i++)
            {
                //check all clients for data
                if( (sockfd=client[i].fd)<0)
                    continue;
                if(client[i].revents & ( POLLRDNORM | POLLERR))
                {
                    if((n=read(sockfd,buf,MAXLINE))<0)
                    {
                        if(errno==ECONNRESET)
                        {
                            //conncetion reset by client
                            Close(sockfd);
                            client[i].fd=-1;
                        }
                        else
                            err_sys("read error");
                    }
                    else if(n==0)
                    {
                        //connection close by client
                        Close(sockfd);
                        client[i].fd=-1;
                    }
                    else    Writen(sockfd,buf,n);
                   
                   if(--nready<=0)
                        break;
                }
            }
        }
    }

    http://itlab.idcquan.com/linux/c/816050.html

     

     

  • 相关阅读:
    转载:MyBatis获取插入记录的自增长字段值
    006---抽象类
    005---组合
    004---继承与派生
    003---属性查找和绑定方法
    002---类与对象
    001---面向对象和面向过程的区别
    017---Django的中间件解决跨域
    10---git安装
    007---归并排序
  • 原文地址:https://www.cnblogs.com/youxin/p/4062306.html
Copyright © 2011-2022 走看看