《APUE》习题16.3

未运行过

#include<initserver.h>
#include<iostream>
#include<netdb.h>
#include<syslog.h>
#include<sys/socket.h>
#include<sys/select.h>
#include<vector>

#define BUFLEN 128
#define QLEN 10

#ifndef HOST_NAME_MAX
#define HOST_NAME_MAX 256
#endif

extern int initserver(int,const struct sockaddr*,socklen_t,int);

using namespace std;

static  int maxfd=-1;//记录最大fd

void server(fd_set fdset,vector<int> fdList){
        int clfd,fdNum,readyFdNum;
        FILE *fp;
        char buf[BUFLEN];

        for(;;){
                if((fdNum=select(maxfd+1,&fdset,NULL,NULL,NULL))<0){
                        err_sys("select error");
                }else if(fdNum>0){//有端口准备好接收连接
                        readyFdNum=fdNum;//记录剩余没处理的,但准备好的套接字
                        for(vector<int>::iterator it=fdList.begin();it<fdList.end();it++){//遍历所有取得的端口的fd
                                if((FD_ISSET(*it,&fdset))!=0){//若此位打开,说明它准备好接收连接
                                        set_cloexec(*it);
                                        if((clfd=accept(*it,NULL,NULL))<0){
                                                syslog(LOG_ERR,"ruptimed:accept error,&s",strerror(errno));
                                                exit(1);
                                        }
                                        set_cloexec(clfd);
                                        if(!(fp=popen("/usr/bin/uptime","r"))){
                                                sprintf(buf,"error:%s\n",strerror(errno));
                                                send(clfd,buf,strlen(buf),0);
                                        }else{
                                                while(fgets(buf,BUFLEN,fp))
                                                        send(clfd,buf,strlen(buf),0);
                                                pclose(fp);
                                        }
                                        close(clfd);
                                        if((--readyFdNum)==0)//若已处理完,退出循环
                                                break;
                                }
                        }
                }
        }

}
int main(int argc,char *argv[]){
    
        struct addrinfo *ailist,*aip;
        struct addrinfo hint;
        int sockfd,err,n;
        char *host;
        fd_set fdset;
        vector<int> fdList(FD_SETSIZE,-1);//初始化fdList,值均为-1,用于保存套接字


        if(argc!=1)
                err_quit("usage: ruptimed");
        if(n=sysconf(_SC_HOST_NAME_MAX)<0)
                n=HOST_NAME_MAX;
        if(!(host=(char *)malloc(n)))
                err_sys("malloc error");
        if(gethostname(host,n)<0)
                err_sys("gethostname error");
        daemonize("ruptimed");
        memset(&hint,0,sizeof(hint));
        hint.ai_flags=AI_CANONNAME;
        hint.ai_socktype=SOCK_STREAM;
        hint.ai_canonname=NULL;
        hint.ai_addr=NULL;
        hint.ai_next=NULL;
        if((err=getaddrinfo(host,"ruptime",&hint,&ailist))!=0){
                syslog(LOG_ERR,"ruptimed: getaddrinfo error:&s",gai_strerror(err));
                exit(1);
        }

        FD_ZERO(&fdset);//fdset清零
        for(aip=ailist;aip!=NULL;aip=aip->ai_next){
                if((sockfd=initserver(SOCK_STREAM,aip->ai_addr,aip->ai_addrlen,QLEN))>=0){
                        FD_SET(sockfd,&fdset);//在fdset增加该套接字             
                        fdList.push_back(sockfd);//在fdList中增加该套接字
                        if(sockfd>maxfd)
                                maxfd=sockfd;
                }

        }
        server(fdset,fdList);
        exit(1);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值