2011-12-23 3 views
6

나는 간단한 클라이언트 및 서버 C 프로그램을 작성하고 서로 다른 터미널에서 서로 통신하려고합니다.적절한 FIFO 클라이언트 - 서버 연결

서버는 공용 FIFO를 만들고 클라이언트를 기다려야합니다. 한편 클라이언트는 서버의 응답을 통해 자신의 FIFO를 생성합니다. 클라이언트의 작업은 큐에 의해 생성 된 이름을 서버에 전송하고 ls 명령의 결과를 반환합니다.

답변을 검색했습니다 (예 : fifo-server-program, example-of-using-named-pipes-in-linux-bash, how-to-send-a-simple-string-between-two-programs-using-pipes). 세 번째 링크의 코드로 시작하여 천천히 수정했습니다.

지금 얻은 것은 클라이언트가 사용자로부터 입력을 받아서 서버로 보내고 수신하는 것입니다. 그러나 그것은 단지 한 번 작동합니다. 나는 이유를 모른다. 주요 기능의 본체는 아래와 같습니다. 어떤 도움을 주셔서 감사합니다.

편집 : 나는 그것을 얻었다! : D 아래 코드는 누군가를 도울 것입니다.

server.c 코드 :

#include <unistd.h> 
#include <stdio.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <string.h> 

int main(int argc, char* argv[]) 
{ 
    int fds[2]; 
    char tab[BUFSIZ]; 
    int fd, n; 

    char *myfifo = "/tmp/serwer"; 
    char *myfifo2 = "/tmp/client"; 

    pipe(fds); 
    mkfifo(myfifo,0666); 

    while(1) 
    { 
     fds[0]=open(myfifo2,O_RDONLY); 
     fds[1]=open(myfifo,O_WRONLY); 

     read(fds[0],tab,BUFSIZ); 

     if (strcmp("klient",tab)==0) { 
      printf("Od klienta: %s\n",tab); 
      fd=open(tab,O_WRONLY); 

      if(fork()==0) 
      { 
       dup2(fds[1],1); 
       close(fds[1]); 
       execlp("ls","ls","-l",NULL); 
       close(fds[0]); 
       close(fds[1]); 
      } 
      else 
      { 
       dup2(fds[0],0); 
       n = read(fds[0],tab,BUFSIZ); 
       write(fd,tab,n); 
       close(fds[0]); 
       close(fds[1]); 
      } 
     } 
     memset(tab, 0, sizeof(tab)); 
     close(fd); 
     close(fds[0]); 
     close(fds[1]); 
    } 

    unlink(myfifo); 
    return 0; 
} 

client.c 코드 :

#include <unistd.h> 
#include <stdio.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <string.h> 

int main(int argc, char* argv[]) 
{ 
    int fds[2]; 
    char *myfifo = "/tmp/serwer"; 
    char *myfifo2 = "/tmp/client"; 

    mkfifo(myfifo2,0666); 
    fds[0]=open(myfifo,O_RDONLY); 
    fds[1]=open(myfifo2,O_WRONLY); 

    char tab[BUFSIZ]; 
    memset(tab, 0, sizeof(tab)); 

    write(fds[1],"klient",6); 
    perror("Write:"); //Very crude error check 
    read(fds[0],tab,sizeof(tab)); 
    perror("Read:"); // Very crude error check 

    printf("Odebrano od serwera: %s\n",tab); 

    close(fds[0]); 
    close(fds[1]); 
    unlink(myfifo2); 
    return 0; 
} 
+1

이 코드에서는 분명하지 않습니다. 출력되는 ls 출력을 얻었거나 작은 msg를 보내는 중입니까? 이 시나리오의 일반적인 함정은 클라이언트가 입력을 기다리는 동안 서버가 입력을 기다리고 있다고 교착 상태가 발생한다는 것입니다. 아무도 아무것도 보내지 않기 때문에 그들은 영원히 기다린다. – Duck

+0

아니요, ls 명령이 아직 작동하지 않습니다. 이러한 프로그램은 한 번 작동합니다. 서버는 메시지를 기다리고 클라이언트로 반환하며 클라이언트는 닫을 수 있습니다. 다른 메시지를 보내려고하면 클라이언트와 서버가 모두 응답하지 않게됩니다. – uluroki

답변

5

은 왜 그냥 서버에 모두 FIFO 년대를 관리하지 않는? 코드를 변경하기 만하면 올바르게 작동합니다.

실제로 많은 클라이언트를 지원하는 서버로 클라이언트 - 서버 관계를 원한다면 소켓이 더 나은 선택 일 수 있습니다.

client.cpp

#include <stdio.h> 
#include <fcntl.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <unistd.h> 

int main() 
{ 
    int client_to_server; 
    char *myfifo = "/tmp/client_to_server_fifo"; 

    int server_to_client; 
    char *myfifo2 = "/tmp/server_to_client_fifo"; 

    char str[BUFSIZ]; 
    printf("Input message to serwer: "); 
    scanf("%s", str); 


    /* write str to the FIFO */ 
    client_to_server = open(myfifo, O_WRONLY); 
    server_to_client = open(myfifo2, O_RDONLY); 
    write(client_to_server, str, sizeof(str)); 

    perror("Write:"); //Very crude error check 

    read(server_to_client,str,sizeof(str)); 

    perror("Read:"); // Very crude error check 

    printf("...received from the server: %s\n",str); 
    close(client_to_server); 
    close(server_to_client); 

    /* remove the FIFO */ 

    return 0; 
} 

server.cpp

#include <fcntl.h> 
#include <stdio.h> 
#include <sys/stat.h> 
#include <unistd.h> 
#include <string.h> 

int main() 
{ 
    int client_to_server; 
    char *myfifo = "/tmp/client_to_server_fifo"; 

    int server_to_client; 
    char *myfifo2 = "/tmp/server_to_client_fifo"; 

    char buf[BUFSIZ]; 

    /* create the FIFO (named pipe) */ 
    mkfifo(myfifo, 0666); 
    mkfifo(myfifo2, 0666); 

    /* open, read, and display the message from the FIFO */ 
    client_to_server = open(myfifo, O_RDONLY); 
    server_to_client = open(myfifo2, O_WRONLY); 

    printf("Server ON.\n"); 

    while (1) 
    { 
     read(client_to_server, buf, BUFSIZ); 

     if (strcmp("exit",buf)==0) 
     { 
     printf("Server OFF.\n"); 
     break; 
     } 

     else if (strcmp("",buf)!=0) 
     { 
     printf("Received: %s\n", buf); 
     printf("Sending back...\n"); 
     write(server_to_client,buf,BUFSIZ); 
     } 

     /* clean buf from any data */ 
     memset(buf, 0, sizeof(buf)); 
    } 

    close(client_to_server); 
    close(server_to_client); 

    unlink(myfifo); 
    unlink(myfifo2); 
    return 0; 
} 
4

그것은 단지 때문에 명명 된 파이프가 작동하는 방법의 한 번 작동합니다. 때마다 open 명명 된 파이프에 대한 읽기 다른 프로세스가 쓰기 위해 열 때까지 차단합니다. 그런 다음 쌍을 이루고 파일 기술자가 프로세스를 연결합니다. 어느 한쪽 끝이 그 연결을 닫으면 그 파이프의 끝입니다. 서버가 "다른 연결을 수락"하려면 파이프의 open 및 을 파이프의 기본 루프로 옮겨야하므로 반복해서 페어링 할 수 있습니다.