7

他のフォーラムで何度か見つけた非常に厄介な問題がありますが、適切な解決策を見つけることができません。問題は、recv()が接続の最後の数バイトで0を返すことです。ここにいくつかの背景情報があります。

  • 両方の(クライアント/サーバー)アプリケーションは同じマシンで実行されます。
  • 両方の(クライアント/サーバー)ソケットは非ブロッキングです
  • 転送されるデータサイズは53バイトです。
  • 最後のsend()/ recv()が実行されたときに、(クライアント/サーバー)の両方がshutdownとclosesocketを呼び出します。
  • 私もSO_LINGERと10秒で試しましたが、成功しませんでした

send()を数回(小さなチャンク)呼び出し、クライアント側から53バイトが転送されます。サーバーはrecv()を数回呼び出し(4バイトの要求)、49バイトを読み取ってから、0を返します(54バイト-49バイト、したがって4バイトが欠落しています)。

MSDNといくつかのフォーラムは、非ブロッキングソケットについて次のように書いています。

  • recv()はエラー時に間違いなく<0を返し、errno/WSAGetLastErrorが設定されます
  • 反対側が接続を閉じたとき、recv()は間違いなく=0を返します
  • データが読み取られたとき、recv()は間違いなく>0を返します

MSDNも言います:

SD_SENDまたはSD_BOTHでclosesocketまたはshutdown機能を使用すると、RELEASE信号が制御チャネルに送信されます。ATMは個別の信号チャネルとデータチャネルを使用しているため、最後のデータが宛先に到達する前にRELEASE信号がリモートエンドに到達し、そのデータが失われる可能性があります。考えられる解決策の1つは、最後に送信されたデータと、ATMソケットのclosesocketまたはshutdown関数呼び出しとの間に十分な遅延をプログラミングすることです。

これは、recv()とsend()の例で考慮されています:http://msdn.microsoft.com/en-us/library/windows/desktop/ms740121(v = vs.85).aspx

しかし、それでも成功しません。49バイトを受信した後、すべての接続の10%で割り込みが発生し、接続の90%が成功します。何か案は?どうも。

4

3 に答える 3

16

recv()0 バイトのバッファーを要求した場合、または他のピアが正常に切断された場合にのみ、0 を返します。期待するすべてのデータを受信して​​いない場合は、最初からデータを正しく読み取っていません。実際のコードで質問を更新してください。

于 2012-05-10T01:42:25.263 に答える