4

を行っているため、ソケットのデータが失わclose()れています。

Linux 固有のshutdown()マンページは役に立ちません。

shutdown() 呼び出しにより、sockfd に関連付けられたソケットの全二重接続のすべてまたは一部がシャットダウンされます。SHUT_RD の場合、それ以上の受信は許可されません。SHUT_WR の場合、それ以上の送信は許可されません。SHUT_RDWR がどのようになっている場合、それ以上の受信と送信は許可されません。

Microsoft のMSDNの方がはるかに優れていますが、Windows 固有であるため、Linux との間には違いがあります。

接続されたソケットが閉じられる前にすべてのデータが送受信されるようにするには、アプリケーションは、closesocket を呼び出す前に shutdown を使用して接続を閉じる必要があります。リモート エンドがすべてのデータを送信し、正常な切断を開始したという通知を待機する 1 つの方法は、次のように WSAEventSelect 関数を使用します。

1. Call WSAEventSelect to register for FD_CLOSE notification.
2. Call shutdown with how=SD_SEND.
3. When FD_CLOSE received, call the recv or WSARecv until the function completes with success and indicates that zero bytes were received. If SOCKET_ERROR is returned, then the graceful disconnect is not possible.
4. Call closesocket.

私の質問

  • Linux では、待機FD_CLOSE(ステップ 1) に相当するものは何ですか?

Windows での動作について質問していると思われる回答やコメントが寄せられています。Linux での動作について質問しています。Linux のマンページよりもはるかに明確で完全な Windows のドキュメントを参照しているだけです。

4

2 に答える 2

5

MSDN の提案は、close() に対する私の非常に詳細な回答に従っています。適切にソケットを閉じていませんこれは、ここでの Remy Lebeau の回答と本質的に同じです。

于 2012-10-11T07:07:24.770 に答える
3

引用したMicrosoftのドキュメントに、「通知を待つ1つの方法...」と書かれていることに注意してくださいWSAEventSelect。つまり、それが唯一の方法ではないということです。同じドキュメントでは、代わりに「重複した受信呼び出し」を使用した同様のアプローチについても説明していますWSARecv()。ただし、より一般的な (イベント駆動型ではない) アプローチは、 を呼び出してから、0 (正常な切断) または(-1)が返されるまでループ内でshutdown()呼び出してから、 を呼び出すことです。recv()SOCKET_ERRORclosesocket()

于 2012-10-10T22:04:46.843 に答える