C 如何确保write(2)已将所有数据写入套接字/文件描述符?
我正在使用C 如何确保write(2)已将所有数据写入套接字/文件描述符?,c,sockets,C,Sockets,我正在使用write(man 2 write)将数据写入一个套接字,该套接字具有已建立的、阻塞的和非常慢的TCP连接。我正在写大量的数据write返回写入的实际大小,当然,并非所有数据都是由于(可能)超出此问题范围的原因而写入的 为了确保我将写调用封装在一个小循环中,如下所示: do { ssize_t ret = write(client, p, count); if (ret <= 0) break; p += ret; count -=
write
(man 2 write)将数据写入一个套接字,该套接字具有已建立的、阻塞的和非常慢的TCP连接。我正在写大量的数据write
返回写入的实际大小,当然,并非所有数据都是由于(可能)超出此问题范围的原因而写入的
为了确保我将写调用封装在一个小循环中,如下所示:
do {
ssize_t ret = write(client, p, count);
if (ret <= 0)
break;
p += ret;
count -= ret;
} while (count);
if (count != 0)
return -ENODEV;
do{
ssize_t ret=写入(客户机、p、计数);
如果(ret我建议使用while
循环,而不是do{}while
来保持案例count==0
的一致行为。此外,一些失败案例不是错误:
while (count > 0) {
ssize_t ret = write(client, p, count);
if (ret <= 0) {
if (ret == 0)
return -ENODEV;
if (errno == EINTR)
continue;
else
return -errno;
}
p += ret;
count -= ret;
}
我建议使用while
循环而不是do{}while
来保持案例count==0
的行为一致。此外,一些失败案例不是错误:
while (count > 0) {
ssize_t ret = write(client, p, count);
if (ret <= 0) {
if (ret == 0)
return -ENODEV;
if (errno == EINTR)
continue;
else
return -errno;
}
p += ret;
count -= ret;
}
size\u未完成;
ssize_t ret;
对于(完成=0;完成<大小;完成+=返回){
ret=写入(客户端,buff+完成,大小完成);
if(ret==0)返回-ENODEV;
如果(ret==1&&errno==EINTR){ret=0;continue;}
if(ret==-1)返回-errno;
}
尺寸未完成;
ssize_t ret;
对于(完成=0;完成<大小;完成+=返回){
ret=写入(客户端,buff+完成,大小完成);
if(ret==0)返回-ENODEV;
如果(ret==1&&errno==EINTR){ret=0;continue;}
if(ret==-1)返回-errno;
}
Related:Related:不是我的否决票!你的答案更简洁,不会修改p
或size
。我会相应地编辑我的答案。我不会抱怨否决票,我也不明白。我确实认为在一个循环中保留两个变量,当只需要一个时,通常是一个坏习惯。不是我的否决票!你的answer更紧凑,不修改p
或size
。我会相应地编辑我的。我不抱怨否决票,也不理解它。我确实认为在一个循环中维护两个变量,当只需要一个时,通常是一个坏习惯。ret
变量有循环作用域。我不得不将它从循环中提升出来循环。你是对的,我的错。太糟糕了,我不能在循环范围内声明它,因为臭名昭著的ssize\t
kludge。从循环中提升很糟糕,但是将增量向下移动到for
主体的末尾也是如此。我将重新选择后者。因此,最后,你得到了我的解决方案(除了残废的for()循环)和+5而不是-1学分)我的情况就这样结束了。ret
varaible有循环作用域。我不得不把它从循环中提出来。你说得对,我的错。太糟糕了,我不能在循环作用域声明它,因为臭名昭著的ssize\t
kludge。从循环中提出来很糟糕,但将增量向下移动到主体的末尾也是如此。我会重新考虑的最后,你得到了我的解决方案(除了残废的for()循环)和+5而不是-1学分),我的情况就这样结束了。。。
size_t done;
ssize_t ret;
for (done = 0; done < size; done += ret) {
ret = write(client, buff + done, size-done);
if (ret == 0) return -ENODEV;
if (ret == -1 && errno == EINTR) { ret = 0; continue; }
if (ret == -1) return -errno;
}