2017-07-27 27 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

其實,我錯過了在服務器端的3個以下行:

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,所以我不得不明確地將其設置爲將SIGIO使事情有效。這裏是服務器端的輸出:

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

現在,我想這是可能的,以處理移動什麼是while循環進入requestHandler函數內部的處理程序中的請求。