写(2)返回零意味着什么,我最终会取得进展吗(非零结果)
What does write(2) return of zero mean and will I eventually make progress (non-zero result)?
我有一个TCP套接字,我在c++ 03程序中写入。在某些情况下,我从write()得到一个零返回结果。write(2)手册页部分说明:
成功时,返回写入的字节数(0表示没有写入)。如果出现错误,则返回-1,并适当设置errno。
那么,0真的意味着没有错误,我应该再次调用write,直到所有内容都写完吗?换句话说,我是否应该只处理一个0,就像我已经为部分写入所做的那样,其中写入的字节数小于我传递给写入的count
,并继续尝试,直到我达到写入的count
字节总数?
我想确保我不会进入一个无限循环,write连续返回零,永远不会取得进展。我应该先调用select()来确保文件描述符在调用write之前准备好吗?我在文件描述符上启用了阻塞
虽然从理论上讲,它可能最终通过或得到一个错误,但我将构建一些针对无限循环的安全性,以防万一。
调用select
等待硬件可能会工作(它当然比只是循环尝试立即再次,这几乎肯定会浪费一些CPU时间-多少取决于很多事情),但这是一个TOCTOU问题-你的系统中的一些其他程序可能已经到达那里之前,你和(再次)填满了可用的系统内存传输通过的时候,你得到write
。
那么,我将按照下面的行来做:
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堆栈,看看是否有任何挂起的错误,如ECONNRESET。
在非阻塞模式下,零长度写入表示socket发送缓冲区已满。当您得到这个时,您应该开始选择该套接字作为writefd,并在套接字变为可写时重试写操作。如果成功,停止将其作为已写文件进行选择。通常不应该使用writefd集合,因为套接字几乎总是准备好写入,除了这里,所以选择器会立即返回。
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- valgrind-hellgrind与泄漏检查的结果不同
- 用C++20 fmt限制结果的总大小
- 如何返回一个类的两个对象相加的结果
- 使用QProcess执行命令,并将结果存储在QStringList中
- 如果我std::dynamic_pointer_cast并且底层dynamic_cast的结果为null,那么返回的sh
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 序列化,没有库的整数,得到奇怪的结果
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- 在更改for循环的第三部分后,未使用for循环结果
- 这行代码在C++类中意味着什么
- 使用++运算符会导致意外的结果
- 为什么在逗号分隔符上下文中将预增量的结果强制转换为void
- C++Brute Force攻击函数不会返回结果
- 你好。。。id_public变量不应该给出结果为 81 和 86 吗?为什么它为两个派生类占用不同的内存位置?
- 算术运算的结果类似于:C浮点变量中的1/3
- ";结果类型必须是可从输入范围的值类型""构造的;创建std::vector时
- 密码登录程序将永远循环并显示不正确的结果
- 视觉检漏仪输出分析:无法解码输出屏幕上的结果意味着什么
- 写(2)返回零意味着什么,我最终会取得进展吗(非零结果)