Maison  >  Questions et réponses  >  le corps du texte

Linux - epoll + problème de réception de données d'E/S non bloquant

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中文网2701 Il y a quelques jours753

répondre à tous(1)je répondrai

  • 滿天的星座

    滿天的星座2017-05-27 17:46:36

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

    répondre
    0
  • Annulerrépondre