美文网首页
slecte实例

slecte实例

作者: 有何不可12317 | 来源:发表于2018-08-20 11:36 被阅读0次

    基础知识参见IO复用基础-slecte-poll-epoll

    #define MAXLINE 1028        // 接收配置更新指令的缓冲区大小
    #define IP_ADDRSTRLEN 128
    int deal_update(int listenfd)
    {
        int i     = 0;
        int n     = 0;
        int maxi  = -1; 
        int maxfd = listenfd;
        int client[FD_SETSIZE]; /* FD_SETSIZE 默认为 1024 */
        int connfd, sockfd;
        int nready;
    
        char buf[MAXLINE];
        char clientIp[IP_ADDRSTRLEN];
        fd_set rset, allset;
    
        for(i = 0; i < FD_SETSIZE; i++)
            client[i] = -1; 
    
        FD_ZERO(&allset);
        FD_SET(listenfd, &allset);
    
        while(1)
        {
            rset = allset;
            struct timeval timeout = {0, 400 * 1000};
    
            nready = select(maxfd + 1, &rset, NULL, NULL, &timeout);
            if (nready < 0)
                perror("select error");
    
    
            if (FD_ISSET(listenfd, &rset))
            {   
                /* new client connection */
                struct sockaddr_in cliaddr;
                socklen_t cliaddr_len = sizeof(cliaddr);
    
                if ((connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len)) < 0) {
                    printf("accept error\n");
                    continue;
                }   
    
                inet_ntop(AF_INET, &cliaddr.sin_addr, clientIp, IP_ADDRSTRLEN);
                printf("received from %s at PORT %d\n", clientIp, ntohs(cliaddr.sin_port));
    
                // 将连接描述符加入到select的数组中
                for (i = 0; i < FD_SETSIZE; i++) {
                    if (client[i] < 0) {
                        client[i] = connfd;
                        break;  // end for
                    }
                }
    
                /* 
                 * 达到select能监控的文件个数上限 1024 
                 * 当达到上限的时候
                 * */
                if (i == FD_SETSIZE) {
                    fputs("too many clients\n", stderr);
                    for (i = FD_SETSIZE; i < 1 ; i--) {
                        if (client[i] > 0) {
                            FD_CLR(client[i], &allset);
                            close(client[i]);
                        }
                    }
                    continue;
                }
    
                /* 添加一个新的文件描述符到监控信号集里 */
                FD_SET(connfd, &allset);
                if (connfd > maxfd)
                    maxfd = connfd; /* select第一个参数需要 */
    
                /* 更新client[]最大下标值 */
                if (i > maxi)
                    maxi = i;
                /* 
                 * 如果没有更多的就绪文件描述符继续回到上面select阻塞监听,负责处理未
                 * 处理完的就绪文件描述符 
                 * */
                if (--nready == 0)
                    continue;
            }
    
            bzero(buf, MAXLINE);
            for (i = 0; i <= maxi; i++)
            {  
                if ( (sockfd = client[i]) < 0)
                    continue;
    
                if (FD_ISSET(sockfd, &rset))
                {  
                    printf("config  updata\n");
                    while ((n = read(sockfd, buf, MAXLINE)) > 0)
                    {
                        printf("buf: %s\n", buf);
    
                        // 接收到数据之后解析 处理
                        Parse_config_update(buf, n);
    
                        bzero(buf, MAXLINE);
                    }
    
                    if ( n== 0 ) {
                        /* 当client关闭链接时,服务器端也关闭对应链接 */
                        close(sockfd);
                        FD_CLR(sockfd, &allset);
                        /* 解除select监控此文件描述符 */
                        client[i] = -1;
                    }
    
                    if (--nready == 0)
                        break;  // end for
                }  
            }  
        }
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:slecte实例

          本文链接:https://www.haomeiwen.com/subject/vxikiftx.html