1 ssize_t readn(int fd, std::string &inBuffer, bool &zero) 2 { 3 ssize_t nread = 0; 4 ssize_t readSum = 0; 5 while (true) 6 { 7 char buff[MAX_BUFF]; 8 if ((nread = read(fd, buff, MAX_BUFF)) < 0) 9 {10 if (errno == EINTR)//慢调用被系统中断时返回的错误,需要冲洗read,所以用continue11 continue;12 else if (errno == EAGAIN)//表示没有数据可读,在ET边缘触发方式下,要求我们做到读无可读13 {14 return readSum;15 } 16 else17 {18 perror("read error");19 return -1;20 }21 }22 else if (nread == 0)23 {24 //printf("redsum = %d\n", readSum);25 zero = true;26 break;27 }28 readSum += nread;29 inBuffer += std::string(buff, buff + nread);30 }31 return readSum;32 }
前提:文件描述符为非阻塞模式,epoll为ET触发方式
调用read之后,根据返回值可分为不同情况:
①nread<0 返回EINTR:该错误为慢系统调用期间进程捕捉到信号使得该系统调用被中断返回时造成的识别码,此时根据需要来重启服务
②nread<0 返回EAGAIN:如果之前已经将读缓冲区中的内容读完,此时该描述符已经变成了不可读状态,由于fd是非阻塞模式,再read就会返回EAGAIN,在ET触发方式下,可表示已经读到了末尾返回readsum
③nread=0 如果客户端关闭连接,那么收到客户的FIN将导致read函数返回0,此时应该修改http为正在断开状态