linux - epoll + non-blocking IO receiving data problem
PHP中文网
PHP中文网 2017-05-27 17:44:36
0
1
767

epoll non-blocking io model, edge trigger I set.

Now the client is a browser. The form uploads a 2M file. The server monitors the readable event. I use recv to obtain it. Why is the data received incomplete and returns -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 is large enough. Could it be that the send speed is slower than the recv speed, causing the tcp receiving buffer to be empty? Does the recv return without blocking? How to deal with it?

    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讲师

reply all(1)
滿天的星座

Because the follow-up data has not arrived yet. You continue to wait for the epoll notification.

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!