首页 未命名正文

linux编程_Linux 服务器模子小结

云返利网 未命名 2020-05-26 09:08:13 17 0

当我们用socket举行编程的时刻,细节上都是选择一个AF_LOCAL,AF_INET再凭据响应的类型填充地址,实在凭据通讯需求,有几种简朴的服务模子可供选用,掌握了这些框架再连系socket高度的抽象,可以为我们编写简朴的服务器程序提供指导

循环服务

用户请求服务需要排队,服务器一次只能服务一个客户,服务完才气对下一个客户举行服务。ATM机就是这个1vs1模子。udp服务器也经常使用这个模子

//模子伪代码
main{
    //获得侦听文件描述符
    listenfd=socket();
    
    //准备地址addr
    
    //(listenfd,100);
    
    while(1){将服务器的addr和listenfd绑定
    bind(listenfd,addr)
    
    //最先侦听,设置缓冲行列长度
    listen(listenfd,100);
    
    while(1){
        //若是侦听到义务就获取sockfd
        int sockfd = accept(listenfd);  //listenfd默认是壅闭IO,没义务时历程会sleep
        
        //通讯...
        
        close(sockfd);
    }
}

多历程并发服务

多历程只是放listen到请求的时刻,不是在原历程中处置请求,而是在子历程中处置,父历程继续侦听请求。多历程的利益父历程不必守候子历程处置完一个请求才气获取下一个请求,而是只要有请求就fork一个子历程处置,这样就可以实现并发服务器。多历程并发的更现实的方案是使用历程池来实现。

//模子伪代码
main{
    //获得侦听文件描述符
    listenfd=socket();
    
    //准备地址addr
    
    //将服务器的addr和listenfd绑定
    bind(listenfd,addr)
    
    //最先侦听,设/准备地址add置缓冲行列长度
    listen(listenfd,100);
    
    while(1){
        //若是侦听到义务就获取sockfd
        int sockfd = accept(listenfd);  //listenfd默认是壅闭IO,没义务时历程会sleep
        pid=fork();
        if(0 == pid){
            //子历程一定要首先关闭listenfd,防止和父历程一起侦听
            //也可以在父历程socket(,,SOCK_CLOEXEC);
            close(listenfd);
                    
            while(1){
                ret=read(sockfd);
                if(0 == ret) break;
                //通讯...
            }
        
            exit(0);
        }
    }
}

多线程并发服务

使用多线程实现并发和多历程类似,然则建立一个线程的开销比建立一个历程小得多,需要注重的是使用多线程需要做好对临界资源的珍爱。现实操作经常使用线程池来实现多线程并发服务。

//模子伪代码
void* communicate(void* arg){
    int sockfd=(int)arg;
    while(1){
        ret=read(sockfd);
        if(0 == ret) break;
        //通讯...
    }
}

main{
    //获得侦听文件描述符
    listenfd=socket();
    
    //准备地址addr
    
    //将服务器的addr和listenfd绑定
    bind(listenfd,addr)
    
    //最先侦听,设置缓冲行列长度
    listen(listenfd,100);
    
    while(1){
        //若是侦听到义务就获取sockfd
        //listenfd默认是壅闭IO,没义务时历程会sleep
        int sockfd = accept(listenfd);  
        pthread_create(tid,communicate,(void*)&sockfd);
        }
    }
}

I/O多路复用并发服务

//模子伪代码
main{
    //获得侦听文件描述符
    listenfd=socket();
    
    //准备地址addr
    
    //将服务器的addr和listenfd绑定
    bind(listenfd,addr)
    
    //最先侦听,设置缓冲行列长度
    listen(listenfd,100);
    
    //准备侦听工具,和响应的触发事宜的聚集
    monitor_set_1[i]={fds...}   //监控I/O有数据流入
    monitor_set_2[i]={fds...}   //监控I/O变得可写

    while(1){
        //监控工具,若是有事宜发生就返回
        poll(monitor_set_1,monitor_set_2)
        for(n=0;n<maxfd;n++){       //poll返回,说明有(一些)事宜被触发,依次处置这些触发了事宜的文件描述符
            if(一个fd有数据流入){
                if(是listenfd有数据流入){
                    //获取sockfd
                    int sockfd = accept(listenfd)
                    
                    //将这个sockfd加入监听有数据流入可写的聚集
                    add_mem(moniter_set_1,sockfd)
                }else {     //不是listenfd有数据流入,而是之前加入的sockfd有数据流入
                    
                    //读取信息
                    read(fd,&msg)
                    
                    //将其挪入加入监控可写事宜的聚集
                    add_mem(monitor_set_1,fd)
                }
            }else{  //一个fd变得可写了
                
                //写入信息
                write(fd,&msg)
                
                //将其挪入监控可读的聚集
                add_mem(monitor_set_1,fd)
            }
        }
    }
}
}

【关于云返利网】

云返利网是阿里云、腾讯云、华为云产品推广返利平台,在各个品牌云产品官网优惠活动之外,云返利网还提供返利。您可以无门槛获得阿里云、华为云、腾讯云所有产品返利,在官网下单后就可以领取,无论是自己用、公司用还是帮客户采购,您个人都可以获得返利。云返利网的目标是让返利更多、更快、更简单!详情咨询13121395187(微信同号)