1. ホーム
  2. c

[解決済み】SIGPIPEを防止する方法(または適切に処理する方法)について)

2022-04-02 12:47:46

質問

TCPまたはローカルのUNIXソケットで接続を受け付け、簡単なコマンドを読み取り、(コマンドに応じて)応答を送信する小さなサーバープログラムを持っています。

問題は、クライアントが回答に関心を持たず、時には早期に終了してしまうことがあることです。 そのため、そのソケットに書き込むと SIGPIPE で、私のサーバーがクラッシュしてしまいます。

ここでクラッシュを防ぐためのベストプラクティスは何でしょうか?相手側がまだ読んでいるかどうかを確認する方法はありますか? ( select() は、ソケットが書き込み可能であると常に言うので、ここでは動作しないようです)。それとも SIGPIPE をハンドラで指定し、それを無視するのでしょうか?

どのように解決するのですか?

一般的には SIGPIPE を作成し、コード内で直接エラーを処理します。 これは、C言語のシグナルハンドラには、できることに多くの制限があるためです。

最も移植性が高いのは SIGPIPE ハンドラから SIG_IGN . これにより、ソケットやパイプへの書き込みが原因で SIGPIPE シグナルを送信します。

を無視するには SIGPIPE シグナルを使用するには、次のコードを使用します。

signal(SIGPIPE, SIG_IGN);

を使用している場合は send() の呼び出しで、もう一つの選択肢は MSG_NOSIGNAL オプションを指定すると SIGPIPE の動作を呼び出しごとにオフにします。 すべてのオペレーティングシステムが MSG_NOSIGNAL フラグを使用します。

最後に、このような場合にも SO_SIGNOPIPE で設定できるソケットフラグです。 setsockopt() を使用すると、一部のオペレーティングシステムで これによって SIGPIPE は、設定されたソケットへの書き込みによってのみ引き起こされます。