2017-07-26 11 views
0

シグナルに慣れていないので、ソケットプログラミングの実践として、UDPエコーサービスでSIGALRMを設定しようとしています。
ここで私はUDPソケットを持っています。クライアントは文字列をサーバーに送り、応答を待ちます(ここでは文字列はサーバーによってエコーされます)。
目的は、SIGALRMを設定し、サーバからの応答がない場合やUDPパケットが失われた場合に、クライアントが文字列を数回再送信するようにすることです。ここでC - SIGALRMが受信されていない

は、私はあなたが私のgithub repo(ライン51)に

unsigned int tries = 0; 

void CatchAlarm() 
{ 
    tries += 1; 
} 

int main(int argc, char **argv) 
{ 
    // SKIPPED 
    // ... 
    struct sigaction handler; 
    handler.sa_handler = CatchAlarm; 
    handler.sa_flags = 0; 
    if(sigfillset(&handler.sa_mask) < 0) 
     return 1; 

    if(sigaction(SIGALRM, &handler, 0) < 0) 
     return 2; 

    ssize_t bytes; 

    bytes = sendto(servSock,...); 

    while((bytes = recvfrom(servSock,...)) < 0) { 
     // alarm went off 
     if(errno == EINTR) { 
      // try 5 times 
      if(tries < 5) { 
       bytes = sendto(servSock,...); 
      } else { 
       fprintf(stdout, "no response, waiting...\n"); 
      } 
     } else { 
      fprintf(stdout, "failed to get data\n"); 
      return 3; 
     } 
    } 
    // recvfrom() got something, cancel timeout 
    alarm(0); 
    fprintf(stdout, "received %d bytes of data\n", bytes); 
    close(servSock); 
} 

SIGALRM-いるclient.cの詳細を取得することができ、小さなサンプルを使用してと...長い行を簡素化私はクライアントを実行すると、SIGALRMシグナルを受信せず、UDPパケットは最初の試行で失われますか?
クライアントは文字列の送信を再試行せず、5回の試行後に終了します。代わりに、サーバーの応答を永遠に待ちます。
クライアントがSIGALRMを取得できない理由を教えてください。
ここに何か迷ったのですか?

+1

あなたは 'alarm(0)'行を持っています。私が何かを逃していない限り、アラームをもっと大きな値に設定したことはないので、アラーム信号が届かない。 (もちろん、あなたが省略したコードの中にあるかもしれませんが、コンパイルできないコードを表示してはいけません。質問している動作をコンパイルして表示するMCVE(MCVE)が必要です。) –

+0

@JonathanLefflerあなたが正しいです、私は完全な&コンパイル可能なサンプルを書いていたはずですが、あなたの説明が完全なコードなしでも答えが分かり、信号で深くなり、alarm()関数の使用にもっと注意を払うでしょう。ありがとう –

答えて

2

GitHubレポのあなたのコードは、0以外の番号を持つalarm()を決して呼び出しません。あなたが実際にアラーム信号を要求しない限り、自動的にアラーム信号が届くことはありません。あなたのプロセスを送信するための他のプロセスに依存して、アラーム信号は弾力性がありません。

関連する問題