2012-12-18 4 views
0

두 개의 C 파일 server.c와 client.c가 있습니다. 서버는 fifo 파일을 생성하고 입력을 기다리는 동안 지속적으로 읽어야합니다. 클라이언트는 PID를 가져 와서 FIFO에 PID를 씁니다.FIFO에 pid를 쓰십시오 - C

int main(){ 
    int fd; 
    int fd1; 
    int bytes_read; 
    char * buffer = malloc(5); 
    int nbytes = sizeof(buffer); 

    if((fd = mkfifo("serverfifo",0666)) == -1) printf("create fifo error"); 
    else printf("create fifo ok"); 

    if ((fd1 = open("serverfifo",O_RDWR)) == -1) printf("open fifo error"); 
    else{ 
     printf("open fifo ok"); 
     while(1){ 
      bytes_read = read(fd,buffer,nbytes); 
      printf("%d",bytes_read); 
      } 
     } 

return(0); 
} 

그리고 내 클라이언트 파일 : 나는군요

int main(){ 

    int fd; 
    int pid = 0; 
    char *fifo; 
    int bytes; 

    if ((pid = getpid()) == 0) printf("pid error"); 
    char pid_s[sizeof(pid)]; 
    sprintf(pid_s,"%d",pid); 


    if ((fd = open ("serverfifo",O_RDWR)) == -1)printf("open fifo error"); 
    else { 
    printf("open fifo ok"); 

     bytes = write(fd,pid_s, sizeof(pid_s)); 
     printf("bytes = %d",bytes); 

    } 

    close(fd); 
return(0); 
} 

두 가지 주요 문제가있다 : 이것은 내가 처음 시작 내 서버에 파일을 인 내가 파일에 PID를 쓸 때 그것은 반환 필자가 작성한 바이트 수는 괜찮아 보이지만 fifo 파일의 속성을 확인하면 0 바이트가됩니다. 두 번째 문제는 읽기가 작동하지 않는다는 것입니다. 인쇄하기 전에 printf를 실행하지만 읽지 않은 후에는 아무것도 반환하지 않고 그냥 멈 춥니 다. 사이트에 유사한 게시물이 많이 있다는 것을 알고 있지만 도움이되는 정보를 찾을 수 없습니다. CodeBlocks와 함께 Ubuntu 및 GCC 컴파일러를 사용하고 있습니다.

+1

fifos는 정규 파일이 아닙니다. 파일의 크기가 0이라고보고하면 괜찮습니다. – yiding

+1

나는이 코드의 모든 것이 어쨌든간에 잘못되었다는 것을 두려워합니다. 또한 코드 형식이 지저분하고 모호합니다. 클라이언트/서버 다중 프로세스 응용 프로그램을 진행하기 전에 C 프로그래밍에 대한 좋은 책을 읽는 것이 좋습니다. – Lundin

답변

3

당신이 예상 크기 읽고 모르는 PID를 직렬화

sizeof(pid)은 문자열 표시가 아닌 pid 값의 크기를 반환합니다. 즉, 아키텍처에 따라 sizeof(int)이 4 또는 8입니다. 그런 다음 인쇄를 계속하십시오. 이 기능이 작동하면 운이 좋으면 작동합니다 (64 비트 시스템에 있음). 올바른 방법은, 당신이 전혀하지 않기로 결정했다면, 적절하게 큰 버퍼를 할당하고, snprintf를 사용하여 오버플로가 없는지 확인하는 것입니다. 이 같은 PID를의 5 개 자리에 맞는, 그래서 뭔가 할 것입니다 :

물론
char pid_s[8]; 
snprintf(pid_s, sizeof(pid_s), "%d", pid); 

, 서버 대신

write(fd, (void*)&pid, sizeof(pid)) 

이제 PID의 원시 바이트를 모두 함께이 단계를 건너 뛰고 보낼 수 있습니다 비슷한 실수를합니다 다시

char * buffer = malloc(5); 
int nbytes = sizeof(buffer); 

sizeof(buffer) 반환 4 또는 8,하지만 당신은 힙 (사용의 malloc)에 할당 할 경우, 5 바이트,이 작업을 수행하는 올바른 방법을 할당입니다 :

char* buffer = malloc(8); 
int nbytes = 8; 

대안는 스택에 할당 할 수는 어레이로 전달하면

char buffer[8]; 
int nbytes = sizeof(buffer); 

를 sizeof는 점에서 일종의 마법, 상기 배열의 크기를 리턴 (8 * 1) 이 경우에.

읽고있을 때 5 바이트를 읽습니다. 이전 버그로 인해 8 바이트를 기록했기 때문에 충분하지 않을 수 있습니다. 또한 읽기가 기록 된 것보다 적은 반환 할 수 있습니다

// client 
char pid_s[8]; 
snprintf(pid_s, sizeof(pid_s), "%d", pid); 
write(fd, pid_s, sizeof(pid_s)); 

// server 
char pid_s[8]; 
read(fd, pid_s, sizeof(pid_s)); 

참고 : 실제로 문자열을 읽고 쓸 수 있다면 당신은 당신이 뭔가를 할 것, 또한이

int pid; 
read(fd, (void*)&pid, sizeof(pid)); 

처럼 읽어야한다 그리고 당신은 다시 읽으려고 전화를해야합니다 ...

+0

좋은 분석. 서버에서'O_RDONLY' 대신'O_RDWR'을 사용하고 클라이언트에서'O_WRONLY'를 사용하는 것은 사소한 문제입니다. 열리는 것이 막히지 않을 것임을 의미합니다. 'printf()'문장은 줄 바꿈이 없어서 흐름을 완벽하게 추적하지 않습니다. 'fd'는'mkfifo()'의 결과에 할당되고,'fd1'은'open()'의 결과에 할당됩니다. 그러나'fd' (mkfifo()가 성공하면 stdin, 그렇지 않으면 오류). 'fd1'을'fd'로 이름을 바꾸고'mkfifo()'의 결과를 저장하지 마십시오. 종료하기 전에 서버에서 파일을 닫고 FIFO를'unlink()'하십시오. –

+0

도움을 주셔서 감사합니다, 나는 꽤 많은 실수를하고 있습니다. – user1895293

0

글쎄,이 코드에는 많은 실수가 있습니다 ... 먼저 sizeof가 그처럼 작동하지 않습니다. 왜 pid를 직렬화합니까?

이 잘못 :

char pid_s[sizeof(pid)]; 

123456는 int이며 그것은 크기가 4 인이 배열에 맞지 않는 만 3 문자는 ...

를 인쇄 할 수 있습니다 그리고 당신은 시도하고 있기 때문에 당신은 최악의 경우를 타고 '\ 0'10 + 1 쓰기하지 않는 많은 일이 잘못 여기에 있습니다 ...

+1

귀하의 진술이 정확하고 포스터가 가지고있는 실제적인 문제점을 반영하고 있지만,이를 수정하면보고되는 문제가 해결 될 것 같지 않습니다. 이 경우 귀하의 게시물은 대답이 아니라 주석이어야합니다. – mah

관련 문제