2011-12-23 11 views
6

私は、単純なクライアントとサーバのCプログラムを書いて、別々の端末でお互いに通信しようとしています。適切なFIFOクライアント - サーバ接続

サーバーは、パブリックFIFOを作成し、クライアントのために待たなければなりません。その間、クライアントは自分自身のFIFOを作成して、それを介してサーバーの応答が得られます。クライアントのタスクは、キューによって作成された名前をサーバに送信し、lsコマンドの結果を返します。

答えを検索しました。たとえば、fifo-server-programexample-of-using-named-pipes-in-linux-bashhow-to-send-a-simple-string-between-two-programs-using-pipesです。私は第3リンクのコードから始め、ゆっくりと修正しました。私が今持っているもの

は、クライアント、ユーザからの入力を取って、それをサーバに送信し、それをバック受けています。しかし、それは一度しか動作しません。なぜ私は考えていない。主な機能の本体は以下の通りです。私はどんな助けにも感謝します。

編集: 私はそれを動作させました! :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ととをメインループに移動して、それを何度も繰り返してペアにする必要があります。

関連する問題