TCP またはローカル UNIX ソケットで接続を受け入れ、簡単なコマンドを読み取り、(コマンドに応じて) 応答を送信する小さなサーバー プログラムがあります。
問題は、クライアントが応答に興味がなく、早期に終了する場合があるということです。そのため、そのソケットに書き込むと、が発生しSIGPIPE
、サーバーがクラッシュします。
ここでクラッシュを防ぐためのベスト プラクティスは何ですか? 回線の反対側がまだ読み取り中かどうかを確認する方法はありますか? (select()
ソケットは常に書き込み可能と表示されるため、ここでは機能していないようです)。または、SIGPIPE
ハンドラーでキャッチして無視するだけですか?
ベストアンサー1
通常はこれを無視し、コード内で直接エラーを処理する必要がありますSIGPIPE
。これは、C のシグナル ハンドラには実行できる内容に関して多くの制限があるためです。
これを行う最も移植性の高い方法は、SIGPIPE
ハンドラーを に設定することですSIG_IGN
。これにより、ソケットまたはパイプの書き込みによってシグナルが発生するのを防ぐことができますSIGPIPE
。
シグナルを無視するにはSIGPIPE
、次のコードを使用します。
signal(SIGPIPE, SIG_IGN);
呼び出しを使用している場合、別の方法として、呼び出しごとに動作をオフにする オプションをsend()
使用します。すべてのオペレーティング システムがこのフラグをサポートしているわけではないことに注意してください。MSG_NOSIGNAL
SIGPIPE
MSG_NOSIGNAL
SO_NOSIGPIPE
最後に、次のように設定できるソケットフラグも検討するとよいかもしれません。setsockopt()
一部のオペレーティング システム (BSD 由来のものなど) では、これSIGPIPE
が設定されているソケットへの書き込みによって発生するのを防ぎます。