部分读写是指,执行read或者write操作时,读取的或者写入的字节数小于请求的字节数。
部分读的原因有两个,一是接近文件末尾(EOF),二是被信号打断。
部分写的原因也是被信号打断。
其实,recv和send也会出现部分接收或者发送的情况,其原因都是被信号打断。
即使使用MSG_WAITALL这个标志,也会被信号打断。这个标志类似于下面的循环,不过不对EINTR处理。
(其他原因参考man手册,此处不做赘述)
那么,为了处理这种情况,只需要对信号打断情况进行处理即可,此时read,write,recv,send返回-1,errno=EINTR。
ssize_t readn(int fd, void *buf, size_t n)
{
ssize_t numRead;
size_t totRead;
char * buffer;
buffer = buf;
for(totRead = 0; totRead < n;)
{
numRead = read(fd, buffer, n - totRead);
if(0 == numRead)
return totRead;
if(-1 == numRead)
{
if(EINTR == errno)
continue;
else
return -1;
}
totRead += numRead;
buffer += numRead;
}
return totRead;
}
ssize_t writen(int fd, const void * buf, size_t n)
{
ssize_t numWritten;
size_t totWritten;
char * bufffer;
buffer = buf;
for(totWritten = 0; totWritten < n;)
{
numWritten = write(fd, buffer, n - totWritten);
if(-1 == numWritten)
{
if(EINTR == errno)
continue;
else
return -1;
}
totWritten += numWritten;
buffer += numWritte;
}
return totWritten;
}
ssize_t recvn(int sockfd, void * buf, size_t n, int flags)
{
ssize_t numRecv;
size_t totRecv;
char * buffer;
buffer = buf;
for(totRecv = 0; totRecv < n;)
{
numRecv = recv(sockfd, buffer, n - totRecv, flags);
if(0 == numRecv)
return totRecv;// peers has performed an orderly shutdown.
if(-1 == numRecv)
{
if(EINTR == errno)
continue;
else
return -1;
}
totRecv += numRecv;
buffer += numRecv;
}
return numRecv;
}
ssize_t sendn(int sockfd, const void * buf, size_t n, int flags)
{
ssize_t numSend;
size_t totSend;
char * buffer;
buffer = buf;
for(totSend = 0; totSend < n;)
{
numSend = send(sockfd, buffer, n - totSend, flags);
if(-1 == numSend)
{
if(EINTR == errno)
continue;
else
return -1;
}
totSend += numSend;
buffer += numSend;
}
return totSend;
}
本文介绍了如何处理在执行read、write、recv及send操作时可能遇到的部分读写问题,包括被信号打断等情况,并提供了具体的代码实现。
562

被折叠的 条评论
为什么被折叠?



