2016-04-26 10 views
1

を要求します私の質問はサーバーと関連しているだけなので、クライアントを無視しています。コミュニケーションは正常に動作しています。クライアントからリクエストを読み取ることができ、私はそれらに答えることができます。今、私はいつでも、キー 'Q'が押されたときにサーバーを終了したいと言うことができます。readステートメントでコードブロックが別のクライアント要求を待っているので、私はこれを行うことはできません。 stdinを読む方法はありません。C FIFOのクライアントを待っている間に、サーバの標準入力を読み取る方法は、私は、このサーバーのコードを持っているC.</p>でパイプ <p>という名前のLinuxを使用して簡単なIPCシステムを実装しています

これは何かできますか?私はreadステートメントをノンブロッキングのように考えていて、stdinを数秒間読んでから、もう一度受信リクエストをチェックしてみてください。私は検索していますが、何も似たものは見つかりませんでした。

UPDATE

私はジャン=バティストYunèsのアプローチを踏襲したが、それはselectだけFIFOのイベントを検出して、私は本当に理由を知らないことが判明。

この

は私がテストだコードです:

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

int main() 
{ 
    int result, fd, maxDescriptor; 
    char input[20], texto[100]; 

    mknod("fifo", S_IFIFO | 0666, 0); 
    fd = open("fifo", O_RDWR); // RDWR to avoid EOF return to select 

    fd_set readset; 
    FD_ZERO(&readset); 
    FD_SET(fileno(stdin), &readset); 
    FD_SET(fd, &readset); 

    maxDescriptor = fileno(stdin) > fd ? fileno(stdin) : fd; 

    while(1) 
    { 
     result = select(maxDescriptor+1, &readset, NULL, NULL, NULL); 

     if(result == -1) 
      perror("select()"); 
     else if(result) 
     { 
      puts("data available."); 

      if(FD_ISSET(fileno(stdin), &readset)) 
      { 
       scanf("%s", input); 
       printf("%s\n", input); 

       if(strcmp(input, "Q") == 0) 
        break; 
      } 

      if(FD_ISSET(fd, &readset)) 
      { 
       read(fd, texto, 100); 
       printf("lido:\n%s\n", texto); 
      } 
     } 
     else 
      puts("no data."); 
    } 

    unlink("fifo"); 
    return 0; 
} 

UPDATE 2:

ジャン=バティスト・Yunèsが指摘したように、それは自動的にリセットされませんので、FD_SETをリセットする必要があります。ここで

は、最終的な作業コードです:

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

int main() 
{ 
    int result, fd, maxDescriptor; 
    char input[20], texto[100]; 

    mknod("fifo", S_IFIFO | 0666, 0); 
    fd = open("fifo", O_RDWR); // RDWR to avoid EOF return to select 

    fd_set readset; 
    FD_ZERO(&readset); 
    FD_SET(fileno(stdin), &readset); 
    FD_SET(fd, &readset); 

    maxDescriptor = fileno(stdin) > fd ? fileno(stdin) : fd; 

    while(1) 
    { 
     result = select(maxDescriptor+1, &readset, NULL, NULL, NULL); 

     if(result == -1) 
      perror("select()"); 
     else if(result) 
     { 
      puts("data available."); 

      if(FD_ISSET(fileno(stdin), &readset)) 
      { 
       scanf("%s", input); 
       printf("%s\n", input); 

       if(strcmp(input, "Q") == 0) 
        break; 
       } 

      if(FD_ISSET(fd, &readset)) 
      { 
       read(fd, texto, 100); 
       printf("lido:\n%s\n", texto); 
      } 

      FD_SET(fileno(stdin), &readset); 
      FD_SET(fd, &readset); 
     } 
     else 
      puts("no data."); 
    } 

    unlink("fifo"); 
    return 0; 
} 
+4

選択やpollあなたはまた、非同期I/Oを使用してコードを書くことを検討することができます(検索選択) –

+1

あなたが複数のファイル記述子で待ってブロックし、それらのいずれかが読み取りの準備ができているか、書き込み時にブロック解除できるようになります。 "libevent"は、非同期コードの作成を簡素化する素敵なCライブラリです。 –

+1

サーバは主にサービスを無期限に実行し、stdinからの入力を読み取っていません。それらはコミュニケーションチャネルを読み、スクリプトから開始されるか停止される(殺される)。 – kjohri

答えて

4

あなたはselectを使用する必要があります。あなたは両方のチャンネルで待つ必要があります:パイプからのものか標準入力からのものですが、どちらを読むかは決して分かりません。 selectの目的は、プロセスがどのチャネルでも読み書きのために待機するようにすることです。

fd_set readset; 
FD_ZERO(&readset);  // empty set of descriptor to select on 
FD_SET(fd, &readset);  // add the pipe 
FD_SET(stdin, &readset); // add stdin 
result = select(fd + 1, &readset, NULL, NULL, NULL); // now wait for something to read on at least one channel (pipe or stdin) 
if (result>0) { 
    if (FD_ISSET(fd, &readset)) { // test for pipe availability 
     // now read the pipe 
    } 
    if (FD_ISSET(stdin, &readset)) { // test for stdin availability 
     // now read stdin 
    } 
} 
+0

ありがとうございます。 1つの質問、選択するために渡したsocket_fd引数は何ですか? fd + 1でなければならない? – yat0

+0

エラーが修正されました –

+0

ありがとうございます。しかし、私はこの方法を試してみて、FIFOイベントを検出しています。質問を編集してください。 また、 'stdin'を' FD_SET'に渡し、 'FD_ISSET'がエラーを引き起こしていたので、関数' fileno'を使って 'stdin'の整数記述子を取得しました。 – yat0

関連する問題