linux epoll 非阻塞,【linux】epoll + 非阻塞IO接收数据问题

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;

}

}

}

回答

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

你可能感兴趣的:(linux,epoll,非阻塞)