(C++)

2011-12-18 2 views
1

모두, 나는 키 - 값 서버를 설계, 나는 클라이언트를 쓰고, 내가 정말 이상한 일을 발견했을 때, 단순화 된 코드를 볼 수 있어요 :(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()라고 생각하지만, 설명 할 수는 없다.

답변

5

printf(3)은 성능 향상을 위해 내부 버퍼링을 수행하는 C 표준 IO 라이브러리의 일부입니다.

버퍼링에는 세 가지 유형이 있습니다 (none, line 및 block).

적용되는 버퍼링은 부분적으로 쓰기 대상 디스크립터가 2인지 여부와 터미널에 연결되어 있는지 여부에 따라 결정됩니다. (isatty(3) 참조)

stderr (2)로 인쇄하면 버퍼링이 수행되지 않습니다.

인쇄가 다른 설명자에 대해 수행 된 경우, 터미널인지 아닌지에 따라 동작이 변경됩니다. 출력이 터미널 인 경우 출력은 라인 버퍼입니다. 출력이 이 아니고 터미널 (파일, 파이프, 소켓 등) 인 경우 출력은 블록 버퍼입니다.

줄을 버퍼링하면 아무 것도 인쇄하기 전에 \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 */ 
+0

좋은 설명. –

+0

정말로 감사합니다. 도움이됩니다. – Flypig

3

표준 출력은 기본적으로 라인 버퍼되어있다. 완전한 행을 쓰지 않으면, 출력은 할 때까지 버퍼에 보관됩니다. fflush을 사용하여 스트림을 플러시하거나 setbuf을 사용하여 버퍼링 모드를 변경할 수 있습니다.