epoll + 非阻塞IO接收数据问题

发布于 2022-09-04 23:38:43 字数 2697 浏览 15 评论 0

epoll + 非阻塞io模型 , 我设置的边沿触发.

现在客户端是浏览器,form表单上传一个2M文件, 服务端监听到可读事件, 我用recv获取, 为什么数据会接受不完全,返回-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足够大, 难道是send速度比recv速度慢, 导致tcp接收缓冲区为空, recv不阻塞返回了吗, 该怎么处理呢?

    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;
            }
        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

随波逐流 2022-09-11 23:38:43

因为后续数据还没到。你继续等 epoll 通知呗。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文