【发布时间】:2017-07-21 01:55:04
【问题描述】:
我的数据是自然分段的,并且来自不同的来源,所以我使用 writev 函数如下。
char *buf0 = "short string\n";
struct bar *my_bar;
my_baz = get_my_baz();
iov[0].iov_base = buf0;
iov[0].iov_len = strlen(buf0);
iov[1].iov_base = my_bar;
iov[1].iov_len = sizeof (struct bar);
bytes_written = writev (sockfd, iov, 3);
我想发送我所有的数据。如果writev一次只写入部分数据怎么办,例如:
bytes_written = 1;
如何继续发送剩余数据? 在write函数中,我们可以这样做enter link description here,那么writev呢?
【问题讨论】:
-
文档中的重要说明:“
readv()和writev()执行的数据传输是原子的:writev()写入的数据作为单个块写入不会与其他进程中写入的输出混合”(注意:此保证不是 POSIX 的一部分,Linux 以外的操作系统可能只写入部分数据) -
@BenVoight 这并不排除在非阻塞模式下的短写。
-
@EJP:当然可以,短写甚至自动恢复操作都不会保留原子性。
-
@BenVoigt 您的报价涉及“执行的数据传输”。 IE。 实际上写了什么。它没有说明所有用户提供的数据都会被写入而不管非阻塞模式,套接字发送缓冲区中没有空间等。这将违反非阻塞模式语义。
-
@EJP:从atomic的基本定义开始。原子传输完全有可能具有非阻塞语义,或者整个块适合缓冲区,或者调用失败而不写入任何内容,返回 -1 并将 errno 设置为 EWOULDBLOCK。