前言
通常文件的I/O与字节流套接字上的read和write函数所表现的行为不一样,有时候字节流套接字上调用read和write返回的字节数可能比请求的大小要小,而这样并不表示一个错误,如果在内核中用于套接字的缓冲区满了达到上限了,这时候就需要再次调用read或write函数,因此封装了如下的两个小函数。
在封装的函数里面如果遇到EINTR错误(说明调用被中断)或EAGAIN(可以尝试再读一次),这时候应该继续读或写,以此来处理剩下的字节
/* code from UNIX Network Programing by W.Richard Stevens */
ssize_t readn(int fd, void *vptr, ssize_t n)
{
ssize_t nleft,nread;
char *ptr;
if(fd == -1)
return -1;
ptr = vptr;
nleft = n;
while(nleft > 0)
{
if((nread = recv(fd, ptr, nleft, 0)) < 0)
{
if(errno == EINTR || errno == EAGIAN)
nread = 0;
else
{
perror("read");
return -1;
}
} else if(nread == 0) {
break;
}
nleft -= nread;
ptr += nread;
}
return (n - nleft);
}
/* code from UNIX Network Programing by W.Richard Stevens */
ssize_t writen(int fd, void *vptr, ssize_t n)
{
ssize_t nleft,nwritten;
char *ptr;
if(fd == -1)
return -1;
ptr = vptr;
nleft = n;
while(nleft > 0)
{
if((nwritten = write(fd, ptr, nleft, 0)) < 0)
{
if(errno == EINTR || errno == EAGIAN)
nwritten = 0;
else
{
perror("write");
return -1;
}
} else if(nwritten == 0) {
perror("write ret 0");
syslog(LOG_ERR, "write err(%s:%d)", __FILE__, __LINE__);
return -1;
}
nleft -= nwritten;
ptr += nwritten;
}
return (n - nleft);
}
另外附上一篇介绍select实现[超时]检测:read_timeout;write_timeout;connect_timeout;accept_timeout的文章
https://blog.csdn.net/weixin_36750623/article/details/83307973