2012-01-09 4 views

答えて

9

すべてのデータが受信されるまでrecvブロックを要求できます(MSG_WAITALLフラグ)。しかし、信号が到着した場合、何らかの作業(つまり、データの一部を受信)を行ったシステムコールは、残りを受け取るために自動的にを再起動できません。したがって、MSG_WAITALLであっても、バッファがいっぱいになる前にrecvコールが返される場合があります。これらのケースを処理する準備が必要です。このことを考えると、多くの人々は単にループすることを選択し、MSG_WAITALLのようなほとんど知られていないフラグを気にしません。これはデフォルトでケースである理由については

、心に来ていくつかの理由があります:

  • よくあるご読み取り部分を受信したいが。たとえば、データをインクリメンタルに表示している場合や、別の場所にプロキシする場合や、データが大きすぎる場合は、一度にすべてをバッファにバッファリングすることはできません。結局のところ、すぐにファイルに書き込むだけの場合は、例えば150の代わりに200の書き込みに分割することに気をつけますか?
  • 開始時に必要なデータ量がわからないことがあります。 telnetプロトコルを検討してください。このプロトコルは、BSDソケットAPIが設計された時点で人気がありました。一度にいくつかのバイトを受け取っていますが、期待するデータ量を示す長さフィールドはなく、さらにそのデータをに表示する必要があります。ここでバッファーを埋めるまでブロックするのは意味がありません。 SMTPやIMAPなどのライン指向のプロトコルと同様に、コマンドを受け取ってからどれくらいの期間待っているかわかりません。
  • recvは、提供されるバッファよりもはるかに小さくても、単一のデータグラムを受信するデータグラムソケットによく使用されます。ストリーミングソケットの自然な拡張は、待たずにできるだけ多くを返すことです。あなたが部分的にバッファとにかくに対処するために準備する必要があるため、最も重要なの

しかし、それはデフォルトでそれに対処するために人々を強制的に良いことだので、彼らは早く自分のループのバグを上げる - むしろ、信号が不幸な瞬間に到着するまで隠れたままにしておくよりも。

4

ほとんどの場合、「すべてのデータ」のデータ量はわかりません。たとえば、ライン指向のプロトコルでデータを受信して​​いる場合、行の長さは10バイトまたは65バイトです。

2

ソケットフラグをブロックまたは非ブロックのいずれかに変更できます。特定のケースは実際にブロックするかブロックしないかは関係ありません。

デフォルトで記述する方法でネットワーク機能を動作させることは意味がありません。ストリームが終了しない場合はどうすればプログラムが終了しないのでしょうか?プリマ・フェイシア、これは健康のようには見えないデフォルトの動作。

http://www.scottklement.com/rpg/socktut/nonblocking.htmlを読んで、ブロッキングIOとノンブロッキングIOについて理解してください。

関連する問題