linux中多路复用poll浅析

上次已经说了select模型,poll模型其实和select其实差别不大,poll的实现和select非常相似,只是描述fd集合的方式不同,poll使用pollfd结构而不是select的fd_set结构。只是poll可以改变最大连接个数。上了案例看看
server

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<poll.h>
#include<errno.h>
#include<ctype.h>

#define MAXLINE 80
#define SERV_PORT 8000

int main(int atgc,char*argv[])
{
    int i,maxi,maxfd,listenfd,connfd,sockfd;
    int nready;
    ssize_t n;
    char buf[MAXLINE];
    char str[INET_ADDRSTRLEN];
    socklen_t cliaddr_len;
    struct pollfd clientpoll[FD_SETSIZE];
    struct sockaddr_in  cliaddr,servaddr;

    listenfd  = socket(AF_INET,SOCK_STREAM,0);

    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(SERV_PORT);
    bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr));
    listen(listenfd,20);

    clientpoll[0].fd = listenfd;
    clientpoll[0].events = POLLRDNORM;
    for(i=1;i<FD_SETSIZE;i++)
        clientpoll[i].fd = -1;
    maxi = 0;
    for(;;){
        nready = poll(clientpoll,maxi+1,-1);
        if(nready < 0){
            printf("poll error \n");
            exit(1);
        }

        if(clientpoll[0].revents & POLLRDNORM){
            cliaddr_len = sizeof(cliaddr);
            connfd = accept(listenfd,(struct sockaddr*)&cliaddr,&cliaddr_len);
            printf("received from %s at PORT %d \n",inet_ntop(AF_INET,&cliaddr.sin_addr,str,sizeof(str)),ntohs(cliaddr.sin_port));
            for(i=1;i<FD_SETSIZE;i++)
                if(clientpoll[i].fd<0){
                    clientpoll[i].fd=connfd;
                    break;
                }
            if(i==FD_SETSIZE){
                printf("too many clients\n");
                exit(1);
            }
            clientpoll[i].events = POLLRDNORM;
            if(i>maxi)
                maxi = i;
            if(--nready==0)
                continue;


        }
        for(i=1;i<=maxi;i++){
            if((sockfd = clientpoll[i].fd)<0)
                continue;
            if(clientpoll[i].revents & POLLRDNORM){
                if((n=read(sockfd,buf,MAXLINE))<0){
                    if(errno == ECONNRESET){
                        printf("clientpoll[%d] aborted connection\n",i);

                        close(sockfd);
                        clientpoll[i].fd = -1;
                    }else{
                        printf("read error \n");
                        exit(1);

                        }


                }else if(n==0){

                        printf("clientpoll[%d] closed connection\n",i);

                        close(sockfd);
                        clientpoll[i].fd = -1;
                }else{

                    int j;
                    for(j=0;j<n;j++)
                        buf[j]=toupper(buf[j]);
                    write(sockfd,buf,n);
                }
                if(--nready ==0)
                    break;
            }
        }
 }
    close(listenfd);
    return 0;
}

客户端使用select写的就行
http://blog.csdn.net/u011573853/article/details/52105365

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值