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

标签 c++ sockets blocking file-descriptor

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

On success, the number of bytes written is returned (zero indicates nothing was written). On error, -1 is returned, and errno is set appropriately.

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

我想确保我不会进入无限循环,写入不断返回零并且永远不会取得进展。我应该在调用 write 之前先调用 select() 以确保文件描述符已准备好吗?我已在文件描述符上启用了阻止功能。

最佳答案

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

调用 select 等待硬件可以工作(这肯定比立即循环尝试要好,这几乎肯定会浪费一些 CPU 时间 - 多少取决于很多事情) ,但它是 TOCTOU问题 - 您系统中的某些其他程序可能在您之前到达那里,并且(再次)在您开始写入时填满了可用于传输的系统内存。

所以,我会按照这些思路做一些事情:

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;
  }
}

关于c++ - write(2) 返回零意味着什么?我最终会取得进展(非零结果)吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16625725/

相关文章:

Go 项目的主要 goroutine 永远休眠?

c++ - 静态对象的非静态成员分配在哪里?

c++ - 如何在Vxworks中正确运行Clock-gettime获取准确时间

c++ - 条件运算符在 VS2010 中的正确行为?

winforms - 最佳实践 : Blocking execution while waiting for an Async method

sql-server - SQL Server SELECT 语句导致阻塞

php - C++ 面向对象的 PHP 扩展

php - 为什么 socket_connect() 会返回错误 #2 : "No such file or directory"?

c# - 如何连接到 C# 中的本地套接字?

java - 如何优化简单的套接字通信?