[英]About the read() in unistd.h (C++)
总的来说,我正在设计一个键值服务器,当我编写客户端时,我发现了一件很奇怪的事情,请参见简化代码:
while(1)
{
printf("->:");
read(STDIN_FILENO, buf, sizeof(buf));
write(client_sock, buf, sizeof(buf));
int m = read(client_sock, buf, sizeof(buf));
buf[m] = '\0';
printf("%s", buf);
}
当我运行程序时,它首先要求输入,所以我输入了一些东西,但是什么也没发生! (当我使用其他客户端时,服务器运行良好,并且可以很好地回显某些内容)
然后我只更改一行代码:
printf("\n->:");
然后运行良好! 为什么? 为什么“ \\ n”可以更改输出? 我想可能是read(),但我无法解释
printf(3)
是C标准IO库的一部分,该库执行内部缓冲以提高性能。
有三种类型的缓冲:无缓冲,行缓冲和块缓冲。
应用哪个缓冲部分取决于写入的描述符是否为2
,以及是否连接到终端。 (请参阅isatty(3)
。)
如果打印到stderr( 2
),则不进行缓冲。
如果对任何其他描述符执行了打印,则无论是否为终端,行为都会改变:如果output为终端,则输出为行缓冲 。 如果输出不是终端(文件,管道,套接字等),则输出将进行块缓冲 。
行缓冲时,它在打印任何内容之前等待\\n
。 (或者,如果在发送\\n
之前写足够多的内容使内部缓冲区溢出)。
我推荐的是以下内容:
printf("->:");
fflush(stdout);
read(STDIN_FILENO, buf, sizeof(buf));
/* ... */
printf("%s\n", buf);
这是一个很小的变化; 您将不会在程序启动时得到无意义的空行,并且提示应立即显示..。
您可以使用setvbuf(3)
函数在启动时更改流的缓冲一次,并且如果愿意,也无需再次刷新它。
int err = setvbuf(stdout, NULL, _IONBF, 0);
/* check err */
默认情况下,标准输出是行缓冲的。 如果不写完整的行,则输出将保留在缓冲区中,直到您写完为止。 您可以使用fflush
刷新流或使用setbuf
更改缓冲模式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.