2009-12-06 4 views
1

I이 사용하는 표준 오류 메시지의 번호 인쇄 기존의 C 프로그램 :이 메시지는 또한을 통해 발송되도록TCP 연결을 통해 형식의 메시지를 보내는

fprintf(stderr, ... 

내가이 프로그램을 수정하고 싶습니다를 인터넷을 통한 TCP 연결. (나는 SOCK_STREAM 소켓으로 이미 만들었습니다.) fprintf에 의한 것처럼 인터넷에서 메시지를 보내는 가장 좋은 방법은 무엇입니까?

물론 메시지를 보내기 전에 먼저 얼마나 오래인지 알 필요가 있습니다. 그래서 클라이언트가 먼저 길이를 보낼 수 있으므로 클라이언트는 몇 바이트를 읽어야하는지 알 수 있습니다 ...

모든 아이디어가 가장 만족 스러울 것입니다.

답변

0

sprintf 또는 명시 적 버퍼 크기를 제공해야하는 변형을 (더 잘)보아야한다고 생각합니다.

3

소켓을 연결하면 소켓 파일 설명자에서 fdopen()을 사용하여 스트림으로 열 수 있습니다. 그러면 이 붙어 대신 fprintf()에 전달할 수 있습니다.

+0

고마워요.하지만 그 점을 생각해 보았습니다. 클라이언트가 각 메시지에 대해 얼마나 많은 바이어를 읽어야 하는지를 알기 위해서는 먼저 메시지의 길이를 미리 보내야합니다. . 나는 stderr 대신에 FILE *을 그냥 넘겨서 할 수 있다고 생각하지 않는다. – Charles

+0

모든 메시지가'\ n'으로 끝나면 클라이언트는 읽을 때까지 그냥 읽을 수있다. – caf

+0

...'fdopen()'을 사용하여'FILE *'을 사용하면 읽기 측에서'fgets()','fscanf()'등을 사용하여 쉽게 할 수 있습니다. – mark4o

1

가변 인수 함수 (함수의 printf 계열 작동 방식)에서 출력 호출을 래핑하고 거기에서 모든 작업을 수행하는 것이 좋습니다. 예를 들면 다음과 같습니다.

int multi_log(FILE * stream, int fd, const char * fmt, ...) { 
    char buff[BUFF_MAX] = {0}; 
    int len = 0; 
    va_list args; 
    va_start (args, fmt); 
    len = vsnprintf (buff, BUFF_MAX, fmt, args); 
    va_end (args); 

    fputs (buff, stream); 
    write (fd, buff, len); 
} 

그런 식으로 필요에 따라 기능을 추가하거나 제거 할 수 있습니다.

주의 사항이 vsnprintf에서 반환 된 크기를 사용하여 신청, 신중하게

0

당신은 그것을 어렵게은 필요 이상 만들고있어 당신에게 맨 페이지를 참조하십시오. 바이너리 데이터를 보내고 클라이언트가 메시지 경계를 인식해야한다면 예를 들어 메시지 길이를 먼저 보내거나 메시지 경계를 나타내는 "프레이밍 (framing)"을 사용해야합니다. 하지만이 경우에는 필요하지 않습니다. 위에서 제안한 것과 같은 접근 방식을 사용하여 소켓에 메시지 텍스트를 쓸 수 있습니다.

상대방은 소켓이 닫힐 때까지 텍스트를 읽는 루프에 앉아있을 수 있습니다. 독자가 텍스트를 한 행씩 처리하도록하려면 각 행의 끝을 개행 문자로 표시 할 수 있습니다. 그러면 독자는 수신 된 텍스트를 통해 해당 줄 바꿈 문자를 검색 할 수 있습니다.

까다로운 수있는 유일한 것은 TCP가 메시지 지향이 아닌 바이트 지향적이기 때문에 독자는 보낸 사람이 보낸 것과 동일한 크기의 청크로 항상 텍스트를 가져올 수 없다는 것입니다. (보통 그렇 겠지만, 보장 할 수는 없습니다.) 따라서 독자는 소켓에서 한 번 읽은 행이 행의 일부가되거나 여러 행이 결합 된 경우를 처리 할 수 ​​있어야합니다. 그것은 일어날 수있는 가능성에 대한 코드를 작성하는 한 큰 문제는 아닙니다.

관련 문제