第一点网上论述的很多,是由于设置了非阻塞的fd, 导致写操作资源还没有准备好,直接跳过当前写操作,继续执行.
而我存在的问题是代码逻辑上的错误,导致了Resource temporarily unavailable出现.(注:逻辑上的问题可能导致意想不到的错误,所以代码上要严谨严谨再严谨).
int writen2(int fd, const void* buff, size_t count)
{
int n;
int left = count;
const char* buf(reinterpret_cast<const char*> (buff));
while(left>0)
{
if((n = write(fd, buf, left) <0)) // 问题出现在这里,先进行逻辑判断,后来才进行赋值.
{
if(errno == EINTR || n<0)
n =0;
else
return -1;
}else if(n ==0)
{
if(errno==EAGAIN)
perror("write error");
}
left -= n;
buf += n;
}
return count;
可以看到代码中先进行了逻辑判断,再进行了赋值,这样导致,写入操作一直都没有成功.会处于一直写的过程,直到对应的缓冲区已经写不下了为止.
分析:
首先,对本地的文件进行同样错误代码的测试如下:
#include<unistd.h>
#include<stdio.h>
#include<errno.h>
int writen(int fd, void* buf, int len)
{
int left =len;
char* temp = reinterpret_cast<char* >(buf);
int n=0;
while(left > 0)
{
if((n = write(fd, temp, left)<0))
{
if(errno ==EINTR)
continue;
}else if(n==0)
{
perror("write error");
}
left -= n;
temp+=n;
}
}
int main()
{
FILE* file = fopen("./test", "r+");
int fd = fileno(file);
writen(fd, buf, sizeof(buf));
}
产生的输出结果为:
表明写入成功,只是陷入死循环了而已.因此引起的思考就是,为什么对于accpet的confd却会因此产生EAGIN的错误.
这个问题,我的猜测对于socket操作的判断(这里排除了非阻塞的原因,因为连接完成后是进行阻塞读的),对于write返回为0的操作,都需要报错为EAGAIN或EWOULDBLOCK.
具体write的讲解可以看如下链接:
http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html