C++ 写(2)返回零意味着什么?我最终会取得进展吗(非零结果)?

C++ 写(2)返回零意味着什么?我最终会取得进展吗(非零结果)?,c++,sockets,blocking,file-descriptor,C++,Sockets,Blocking,File Descriptor,我在C++03程序中有一个TCP上的套接字。在某些情况下,我从write()得到零返回结果。write(2)手册页部分说明: 成功时,返回写入的字节数(零表示未写入任何内容)。在出现错误时,返回-1,并正确设置errno 那么,零真的意味着没有错误吗?我应该再次调用write,直到我所写的一切都写完了吗?换句话说,如果写入的字节数小于我传递给写入的count的字节数,我是否应该像对待部分写入那样对待零,然后继续尝试,直到写入的字节总数达到count为止 我想确保我不会进入一个无限循环,写操作不断

我在C++03程序中有一个TCP上的套接字。在某些情况下,我从write()得到零返回结果。write(2)手册页部分说明:

成功时,返回写入的字节数(零表示未写入任何内容)。在出现错误时,返回-1,并正确设置errno

那么,零真的意味着没有错误吗?我应该再次调用write,直到我所写的一切都写完了吗?换句话说,如果写入的字节数小于我传递给写入的
count
的字节数,我是否应该像对待部分写入那样对待零,然后继续尝试,直到写入的字节总数达到
count
为止


我想确保我不会进入一个无限循环,写操作不断返回零,并且永远不会取得进展。在调用write之前,是否应该先调用select()以确保文件描述符已准备就绪?我已经在文件描述符上启用了阻塞。

虽然从理论上讲,它可能会通过或最终会出错,但我会针对无限循环建立一些安全机制,以防万一

调用
select
等待硬件可能会起作用(当然,这比直接循环再次尝试要好,这几乎肯定会浪费一些CPU时间-这在多大程度上取决于很多事情),但这是一个问题-系统中的其他一些程序可能在您之前就已经到达了那里,并且(再次)在您进入
写入时,已填满可用于传输的系统内存

因此,我会按照以下思路做一些事情:

int write_zero_count = 0; 

while(not_all_written)
{
  int res;
  res = select(...);
  ... check if we can write, etc ... 
  res = write(...);
  if (res == 0)
  {
     write_zero_count++;
     if (write_zero_count > max_zero_writes)
     {
        error("Got many writes that sent zero bytes, not good");
        .... do other stuff to log and recover from error or exit? ...
     } 
  }
  else
  {
      write_zero_count = 0;
  }
}
阻塞模式下的
write()
send()
只能在提供零长度时返回零。这几乎肯定是您的编程错误

唯一的例外情况是,如果您使用零长度写入来验证本地TCP堆栈,以查看是否存在任何挂起的错误,如EconReset


在非阻塞模式下,零长度写入意味着套接字发送缓冲区已满。当您收到此消息时,您应该开始选择该套接字作为writefd,并在套接字变为可写时重试写入。如果成功,请停止将其作为writefd进行选择。通常情况下,您根本不应该使用writefd集,因为除了此处之外,套接字几乎总是可以写入的,因此选择器将立即返回。

您确定发生这种情况时没有传递长度为0的值吗?正确,发生这种情况时,我没有传递长度为零的值。“在非阻塞模式下,零长度写入意味着套接字发送缓冲区已满”-你对此有把握吗?我认为这不是正确的说法。如果发送缓冲区已满,写入调用将返回-1,并且errno将设置为EAGAIN或eWoldBlock。我没有传递零长度,因此这可能是Centos 4中的错误。