epoll + nicht blockierendes io-Modell, Kantentrigger, den ich eingestellt habe.
Jetzt ist der Client ein Browser und das Formular lädt eine 2M-Datei hoch. Ich verwende recv, um sie zu erhalten, und gibt -1, errno = EAGAIN zurück
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 ist groß genug. Könnte es sein, dass die Sendegeschwindigkeit langsamer ist als die Empfangsgeschwindigkeit, was dazu führt, dass der TCP-Empfangspuffer leer ist? Wie gehe ich damit um?
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 通知呗。