Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何确保write(2)已将所有数据写入套接字/文件描述符?_C_Sockets - Fatal编程技术网

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