zoukankan      html  css  js  c++  java
  • linux编程---网络编程之复用I/O模型

    模型一:阻塞模型---进程效率低;CPU利用低

    模型二:非阻塞模型---进程效率高;但是CPU利用率低;

    模型三:复用I/O模型---CPU利用率提高

    思想:对于任何一个套接字描述符发生事件时才由系统去唤醒进程,从而不需要因轮询而占用CPU;

    对于I/O复用典型的应用如下:

    (1)当客户处理多个描述字时(一般是交互式输入和网络套接口),必须使用I/O复用。

    (2)当一个客户同时处理多个套接口时,而这种情况是可能的,但很少出现。

    (3)如果一个TCP服务器既要处理监听套接口,又要处理已连接套接口,一般也要用到I/O复用。

    (4)如果一个服务器即要处理TCP,又要处理UDP,一般要使用I/O复用。

    (5)如果一个服务器要处理多个服务或多个协议,一般要使用I/O复用。

    函数:select

    int select(int nfds, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout);
    函数是用来对文件描述符集监视的;只要集合中有文件描述符发生事件了,表示就绪了;
    fd_set *readset, fd_set *writeset, fd_set *exceptset表示该函数监视的事件类型;
    struct timeval *timeout表示来看事件发生前如何操作,是一直等待(NULL),不等待直接返回(0);还是等待一定时间后返回(大于0的值)
    int nfds表示用来设置select检查文件描述符的最大值;故而他检测的值范围是0~nfds-1。
    返回值就是发生事件的个数,如果没有返回0;如果错误则返回-1;

    一个进程启动时,都会打开3个文件:标准输入、标准输出和标准出错处理。这3个文件分别对应文件描述符为0、1和2(宏替换STDIN_FILENO、STDOUT_FILENO和STDERR_FILENO)
     
    效果:此函数让对事件发生过程交给了内核去处理;不像前面阻塞模式中,对于每个套接字描述符都得去等待而降低进程效率;也不像非阻塞中,对于每个套接字描述符都得不断轮询扫描而达到是否有事件发生,而降低CPU利用率。本函数将多个合一的效果,多个套接字事件发生效果,集中到一个套接字集合中,只要有则就可以焕发进程处理。
     
    实例:
    #include "server.h"
    
    int main()
    {
        int listen_fd, connect_fd, max_fd;
        struct sockaddr_in serveraddr, clientaddr;
        char buf[MAXBUF];
        int length;
        fd_set rdfs, tempfs;
        int num;
    
    
        listen_fd = socket(AF_INET, SOCK_STREAM, 0);
    
        memset(&serveraddr, 0, sizeof(serveraddr));
        serveraddr.sin_family = AF_INET;
        serveraddr.sin_port = htons(8000);
        serveraddr.sin_addr.s_addr = inet_addr("192.168.0.104");
    
        bind(listen_fd, (SA *)&serveraddr, sizeof(serveraddr));
        listen(listen_fd, 10);
        //connect_fd = bind();
        
        memset(buf, '', sizeof(buf));
        FD_ZERO(&rdfs);
        FD_SET(0, &rdfs);
        FD_SET(listen_fd, &rdfs);
        max_fd = listen_fd;
        
        int i;
    
        while(1)
        {
            tempfs = rdfs;
            printf("selecting...
    ");
    
            if((num = select(max_fd + 1, &tempfs, NULL, NULL, NULL))== -1)
            {
                perror("select failed!
    ");
                exit(-1);
            }
            else if(num > 0)
            {
                printf("the current fd stream number is : %d
    " , num);
            }
    
            printf("select success...
    ");
        //    sleep(1);
            
            for(i=0; i< max_fd + 1; i++)
            {
                if(FD_ISSET(i, &tempfs))
                {
                    if(i == STDIN_FILENO)
                    {
                        fgets(buf, sizeof(buf), stdin);
                        printf("input :%s",buf);
                    }
    
                    if(i == listen_fd)
                    {
                        length = sizeof(clientaddr);
                        printf("connecting...");
                        connect_fd = accept(listen_fd, (SA *)&clientaddr, &length);
                        printf("connected!
    ");
                        FD_SET(connect_fd, &rdfs);
    
                        if(max_fd < connect_fd)
                        {
                            max_fd = connect_fd;
                        }
    
                        printf("IP: %s port: %d
    ", inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));
                    }
                    else
                    {
                        memset(buf, 0, sizeof(buf));
                        read(i, buf, sizeof(buf));
                        printf("Get Message:%s
    ", buf);
                        close(i);
                        FD_CLR(i, &rdfs);
    
                        if(max_fd == i)
                        {
                            max_fd --;
                        }
                    }
    
                }
            }
        }
    
        return 0;
    }
    程序来源:http://blog.chinaunix.net/uid-26773174-id-3181442.html
     
     
  • 相关阅读:
    洛谷P2737 [USACO4.1]麦香牛块Beef McNuggets(DP,裴蜀定理)
    洛谷P4924 魔法少女小Scarlet
    洛谷P3912 素数个数
    洛谷P4016 负载平衡问题(费用流)
    洛谷P2736 [USACO3.4]“破锣摇滚”乐队 Raucous Rockers
    母函数(生成函数)
    洛谷P4086 [USACO17DEC]My Cow Ate My Homework S
    洛谷P5097 [USACO04OPEN]Cave Cows 2(ST表)
    洛谷P2713 罗马游戏(左偏树)
    洛谷P1260 工程规划
  • 原文地址:https://www.cnblogs.com/miner007/p/3965908.html
Copyright © 2011-2022 走看看