2017-07-27 7 views
0

私はfifoとの単純なクライアント/サーバ通信を作成していますが、シグナルハンドラを使用してクライアント要求を処理しています。シグナルハンドラを使用してfifoから受け取ったデータを処理する

サーバは読み取り専用で非ブロックモードでFIFOを開き、受信した読み取りデータを受信し、クライアントFIFOにいくつかのデータを書き戻します。

これは実際には、サーバー側にシグナルハンドラがない場合にうまく動作します。ここには両側のメインコードがあります。

サーバー:

int main(int argc, char *argv[]) 
{ 
    // install handler 
    struct sigaction action; 

    action.sa_handler = requestHandler; 

    sigemptyset(&(action.sa_mask)); 

    action.sa_flags = SA_RESETHAND | SA_RESTART; 

    sigaction(SIGIO, &action, NULL); 

    if(!makeFifo(FIFO_READ, 0644)) 
     exit(1); 

    int rd_fifo = openFifo(FIFO_READ, O_RDONLY | O_NONBLOCK); // non blocking 

    if(rd_fifo == -1) 
     exit(1); 

    // wait for request and answer 
    while (1) { 
     qWarning() << "waiting client..."; 
     sleep(1); 
     QString msg = readFifo(rd_fifo); 

     qWarning() << "msg = " << msg; 

     if(msg == "ReqMode") { 
      int wr_fifo = openFifo(FIFO_WRITE, O_WRONLY); // blocking 
      writeFifo(wr_fifo, QString("mode")); 
      break; 
     } else 
      qWarning() << "unknow request .."; 
    } 

    close(rd_fifo); 
    unlink(FIFO_READ); 

    return 0; 
} 

クライアント:

int main(int argc, char *argv[]) 
{ 
    int wr_fifo = openFifo(FIFO_WRITE, O_WRONLY); 

    if(wr_fifo == -1) 
     exit(1); 

    // create a fifo to read server answer 
    if(!makeFifo(FIFO_READ, 0644)) 
     exit(1); 

    // ask the server his mode 
    writeFifo(wr_fifo, QString("ReqMode")); 

    // read his answer and print it 
    int rd_fifo = openFifo(FIFO_READ, O_RDONLY); // blocking 
    qWarning() << "server is in mode : " << readFifo(rd_fifo); 

    close(rd_fifo); 
    unlink(FIFO_READ); 

    return 0; 
} 

すべてが期待される(すべてのエラーが適切に処理されていない場合でも、これはこれが可能であることを証明するだけのサンプルコードである)として動作します。

問題は、クライアントがfifoにデータを書き込むときに、ハンドラ(ここでは表示されていませんが、受信した信号で端末にメッセージを出力するだけです)が呼び出されないことです。さらに、サーバーにbash(または他の場所から)kill -SIGIOを送信すると、シグナルハンドラが実行されることを確認しています。

ありがとうございました。デフォルトの信号が私の場合は0だっ送られ、そう私はSIGIOに明示的に設定する必要がありましたので、最後の点が重要だった

fcntl(rd_fifo, F_SETOWN, getpid()); // set PID of the receiving process 

fcntl(rd_fifo, F_SETFL, fcntl(rd_fifo, F_GETFL) | O_ASYNC); // enable asynchronous beahviour 

fcntl(rd_fifo, F_SETSIG, SIGIO); // set the signal that is sent when the kernel tell us that there is a read/write on the fifo. 

答えて

0

は実際に、私は、サーバー側の3次の行を逃しました物事を働かせる。ここでは、サーバ側の出力は次のとおりです。

waiting client... 
nb_read = 0 
msg = "" 
unknow request .. 
waiting client... 
signal 29 
SIGPOLL 
nb_read = 7 
msg = "ReqMode" 

、私はそれがのRequestHandler関数にwhileループの内側にあるものを移動することによって、ハンドラ内で要求を処理することも可能だと思います。

関連する問題