简体   繁体   中英

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? I guess it maybe the read() , but I can't explain it

printf(3) is part of the C standard IO library, which performs internal buffering to provide performance improvements.

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. (See isatty(3) .)

If the printing is done to stderr ( 2 ) then no buffering is done.

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 . 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. (Or if you write enough to overflow the internal buffers before sending a \\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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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