网络编程poll的基本使用例子

poll的用法和select区别并不是很大。非常像。最大文件描述符数量我直接使用FD_SETSIZE了。

比起select来,代码少了一些。也方便了些。使用方式的区别也并不大。但是比select要灵活了

服务端

#include <stdio.h>
#include "unp.h"
int main() {
    int i,maxi,maxfd,listenfd,clifd;
    int n,readycnt;
    char buff[MAXLINE];
    struct pollfd client[FD_SETSIZE];
    //服务端套接口的创建,绑定,监听
    struct sockaddr_in serAddr;
    bzero(&serAddr,sizeof(serAddr));
    serAddr.sin_family=AF_INET;
    serAddr.sin_port=htons(SERV_PORT);
    serAddr.sin_addr.s_addr=htonl(INADDR_ANY);
    listenfd=Socket(AF_INET,SOCK_STREAM,0);
    Bind(listenfd,(SA*)&serAddr,sizeof(serAddr));
    Listen(listenfd,LISTENQ);
    //poll添加监听这个服务端端口的套接口
    client[0].fd=listenfd;
    client[0].events=POLLRDNORM;
    //后面的全部初始化为-1
    for(i=1;i<FD_SETSIZE;i++){
        client[i].fd=-1;
    }
    maxi=0;
    for(;;){
        readycnt=Poll(client,maxi+1,INFTIM);        //开始阻塞,等待就绪的数据
        if(client[0].revents&POLLRDNORM){           //第一个是单独加的服务端端口监控的套接口,如果有数据就绪,就是直接接收客户端连接
            clifd=Accept(listenfd,(SA*)NULL,NULL);  //接收客户端连接
            for(i=0;i<FD_SETSIZE;i++){              //找到一个空的位置
                if(client[i].fd<0)
                    break;
            }
            if(i>=FD_SETSIZE)                       //没有位置了,放不下就直接报错咯
                err_quit("too many clients");
            client[i].fd=clifd;                     //记录这个客户端连接
            client[i].events=POLLRDNORM;            //添加读的监控
            if(i>maxi)                              //修改最大索引
                maxi=i;
            if(--readycnt<=0)                       //如果没有其他就绪的。就不用往后走了
                continue;
        }
        for(i=1;i<=maxi;i++){                       //遍历所有客户端连接
            if(client[i].fd<0)                      //空数据的跳过
                continue;
            if(client[i].revents&(POLLRDNORM|POLLERR)){     //因为有些实现再一个连接上接收到RST时返回的是POLLERR事件。所以这两种事件触发。我们都read下
                if((n=Read(client[i].fd,buff,MAXLINE))<=0){ //如果失败的错误处理
                    if(n==0){
                        Close(client[i].fd);
                        client[i].fd=-1;
                    }
                    else if(errno==ECONNRESET){
                        Close(client[i].fd);
                        client[i].fd=-1;
                    }
                    else
                        err_quit("read err");
                }
                else
                    Writen(client[i].fd,buff,n);    //成功就直接写入返回数据
                if(--readycnt<=0)               //就绪队列完成就结束循环
                    break;
            }
        }

    }
}

 

posted @ 2018-09-29 16:25  李亚金  阅读(799)  评论(0编辑  收藏  举报