6

SO_SNDTIMEOSO_RCVTIMEOを使用してタイムアウトを確認する方法を学習しています。読み取りソケットで使いやすいです。しかし、書き込みタイムアウトを確認したいときは、常に成功を返します。これが私がしたことです:(すべてブロッキングモードで)

  1. サーバーが書き込みを開始する前に、クライアントの読み取りソケットを閉じて終了します
  2. サーバーが書き込みを開始する前にクライアントを終了する
  3. 受け入れ後、書き込み前にサーバーのケーブルを抜きます

まあ、これらのケース書き込みはすべて正常に返されたようです。その理由は、ポートがOSによって管理されるリソースであり、クライアント側では、プログラムがなくなった後もtcp接続がFIN_WAIT2状態を示しているためだと思います。

それで、書き込みがEPIPEEAGAINなどのエラーを受け取る可能性があるいくつかのケースをシミュレートする便利な方法はありますか?

4

3 に答える 3

5

エラーEAGAINを取得するには?
エラー EAGAIN を取得するには、ノンブロッキング ソケットを使用する必要があります。ノンブロッキング ソケットでは、内部 TCP バッファがいっぱいになり、このエラーが返されるように、大量のデータを書き込む (そしてピア側でデータの受信を停止する) 必要があります。

エラー EPIPE を取得する方法?
エラー EPIPE を取得するには、ピア側でソケットを閉じた後、大量のデータを送信する必要があります。この SO Linkから EPIPE エラーに関する詳細情報を取得できます。提供されたリンクで Broken Pipe Error について質問しましたが、受け入れられた回答で詳細な説明が得られます。EPIPE エラーを取得するには、send の flags パラメータを MSG_NOSIGNAL に設定する必要があることに注意してください。それがないと、異常な送信によって SIGPIPE シグナルが生成される可能性があります。

追記事項
TCP は通常、書き込もうとしているデータを内部バッファに格納するため、書き込みの失敗をシミュレートするのは難しいことに注意してください。したがって、内部バッファーに十分なスペースがある場合、すぐにエラーになることはありません。最良の方法は、大量のデータを書き込もうとすることです。SO_SNDBUF オプションを指定してsetsockopt関数を使用して、送信用のバッファ サイズを小さく設定することもできます。

于 2012-06-26T05:20:03.790 に答える
5

フォールト挿入を使用してエラーをシミュレートできます。たとえば、libfiuは、POSIX 関数からのエラーをシミュレートできるサンプル プロジェクトに付属するフォールト挿入ライブラリです。基本的にLD_PRELOAD、通常のシステム コール (を含むwrite) の周りにラッパーを挿入するために使用します。その後、ラッパーは、実際のシステム コールにパススルーするか、任意のエラーを返すように構成できます。

于 2012-06-26T05:37:06.157 に答える
1

一方では受信バッファ サイズを非常に小さく設定し、他方では大きなバッファを送信できます。または、送信バッファを小さく設定し、大きなメッセージを送信してみてください。

それ以外の場合、最も一般的なテスト (私が思うに) は、サーバーとクライアントをしばらく通信させてから、ネットワーク ケーブルを取り外すことです。

于 2012-06-26T05:18:57.567 に答える