Linux - epoll + problème de réception de données d'E/S non bloquant
PHP中文网
PHP中文网 2017-05-27 17:44:36
0
1
842

epoll + modèle io non bloquant, déclencheur de bord que j'ai défini.

Maintenant, le client est un navigateur et le formulaire télécharge un fichier 2M. Le serveur surveille l'événement lisible. J'utilise recv pour l'obtenir. Pourquoi les données reçues sont-elles incomplètes et renvoient -1, errno = EAGAIN.

while(len > 0){                                                                                                                                                                                   
    recvbytes =  recv(client_fd, cur_recv, MAX_RECV_SIZE, 0);                                                                                                                                     
    if(-1 == recvbytes && errno == EAGAIN){
       err_sys("recv http body fail", DEBUGPARAMS);
       return -1;
      }   
    cur_recv += recvbytes;                                                                                                                                                                        
    len -= recvbytes;
 } 

cur_recv est suffisamment grand. Se pourrait-il que la vitesse d'envoi soit plus lente que la vitesse de réception, ce qui rendrait le tampon de réception TCP vide ?

    while(1){

        ret = epoll_wait(epfd, events, MAX_FD, -1);
        
        /* 遍历 */
        for(i = 0; i < ret; i++){
            http_request *hr = (http_request *)events[i].data.ptr;
            
            /* 检测套接字是否存在连接*/
            if(sockfd == hr->sockfd){
                int client_fd;

                while(1){
                    if(-1 == (client_fd = accept(sockfd, (struct sockaddr *) &client_sock, &sin_size))){
                        if((errno == EAGAIN) || (errno == EWOULDBLOCK)){
                            break;
                        }else{    
                            err_sys("accept() fail", DEBUGPARAMS);
                            break;
                        }
                    }
                    set_non_blocking(client_fd);
                    http_request *request = (http_request *)malloc(sizeof(http_request));
                    init_http_request(request, client_fd, epfd);

                    event.data.ptr = (void *)request;
                    event.events = EPOLLIN | EPOLLET | EPOLLONESHOT;  //可读 + 边沿触发 + 避免分配给多个线程
                    if(-1 == (ret = epoll_ctl(epfd, EPOLL_CTL_ADD, client_fd, &event))){
                        err_sys("epoll_ctl fail", DEBUGPARAMS);
                        break;
                    }
                }
            }else{
                if((events[i].events & EPOLLERR) || events[i].events & EPOLLHUP || (!(events[i].events & EPOLLIN))){
                    close(hr->sockfd);
                    continue;
                }
                /*添加到线程池工作队列*/
                if(-1 == add_job(handle_request, events[i].data.ptr)) break;
            }
        }
    }
PHP中文网
PHP中文网

认证高级PHP讲师

répondre à tous(1)
滿天的星座

Parce que les données de suivi ne sont pas encore arrivées. Vous continuez à attendre la notification epoll.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal