简体   繁体   English

关于unistd.h(C ++)中的read()

[英]About the read() in unistd.h (C++)

all, I am designing a Key-Value server, and when I wrote the client, and I found a really strange thing,see the simplified code: 总的来说,我正在设计一个键值服务器,当我编写客户端时,我发现了一件很奇怪的事情,请参见简化代码:

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

when I run the program, it first ask for input, so I input something, but nothing happen! 当我运行程序时,它首先要求输入,所以我输入了一些东西,但是什么也没发生! (the server runs well, and it well echo something, when I use other client) (当我使用其他客户端时,服务器运行良好,并且可以很好地回显某些内容)

then I change the code only one line: 然后我只更改一行代码:

printf("\n->:");

then it runs well! 然后运行良好! why? 为什么? why "\\n" can change the output? 为什么“ \\ n”可以更改输出? I guess it maybe the read() , but I can't explain it 我想可能是read(),但我无法解释

printf(3) is part of the C standard IO library, which performs internal buffering to provide performance improvements. printf(3)是C标准IO库的一部分,该库执行内部缓冲以提高性能。

There are three types of buffering: none, line, and block. 有三种类型的缓冲:无缓冲,行缓冲和块缓冲。

Which buffering is applied is determined in part by whether the descriptor being written to is 2 or not, and if it is connected to a terminal. 应用哪个缓冲部分取决于写入的描述符是否为2 ,以及是否连接到终端。 (See isatty(3) .) (请参阅isatty(3) 。)

If the printing is done to stderr ( 2 ) then no buffering is done. 如果打印到stderr( 2 ),则不进行缓冲。

If the printing is done to any other descriptor, then the behavior changes if it is a terminal or not: if output is a terminal, then the output is line buffered . 如果对任何其他描述符执行了打印,则无论是否为终端,行为都会改变:如果output为终端,则输出为行缓冲 If the output is not a terminal (file, pipe, socket, etc.) then the output is block buffered . 如果输出不是终端(文件,管道,套接字等),则输出将进行块缓冲

When line buffered, it waits for the \\n before printing anything. 行缓冲时,它在打印任何内容之前等待\\n (Or if you write enough to overflow the internal buffers before sending a \\n .) (或者,如果在发送\\n之前写足够多的内容使内部缓冲区溢出)。

What I'd recommend instead is the following: 我推荐的是以下内容:

printf("->:");
fflush(stdout);
read(STDIN_FILENO, buf, sizeof(buf));
/* ... */
printf("%s\n", buf);

It's a small change; 这是一个很小的变化; you won't get a pointless empty line at program start, and the prompt should show up .. promptly. 您将不会在程序启动时得到无意义的空行,并且提示应立即显示..。

You can use the setvbuf(3) function to change the buffering for your stream once, at start up, and never need to flush it again, if you would rather. 您可以使用setvbuf(3)函数在启动时更改流的缓冲一次,并且如果愿意,也无需再次刷新它。

int err = setvbuf(stdout, NULL, _IONBF, 0);
/* check err */

Standard output is line-buffered by default. 默认情况下,标准输出是行缓冲的。 If you don't write a complete line, the output will be held in the buffer until you do. 如果不写完整的行,则输出将保留在缓冲区中,直到您写完为止。 You can use fflush to flush the stream or setbuf to change the buffering mode. 您可以使用fflush刷新流或使用setbuf更改缓冲模式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM