他のフォーラムで何度か見つけた非常に厄介な問題がありますが、適切な解決策を見つけることができません。問題は、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%が成功します。何か案は?どうも。