5

TCPソケットプログラミングでは、 recv()0が返される場合、反対側が接続を閉じたことを示していると見なされます。ただし、AFAIK、TCP RFCは、TCPのペイロードを> 0にすることを義務付けていません。したがって、理論的には、TCPスタックはペイロード0のメッセージを受信できます。

したがって、基本的に私の質問は、recv()サイズが0のペイロードのパケットを受信した場合に何が返されるかということです。0が返された場合、閉じた接続の表示とどのように区別しますか。

4

2 に答える 2

11

ペイロードサイズが0のTCPセグメントはどこにでもあり、実際のほとんどすべてのTCPストリームで発生します。これらは、一方が他方からのデータの受信を確認したいときに送信されますが、独自に送信するデータはありません。(これらは一般に「ACKパケット」として知られていますが、「ACKパケット」はデータを含まない通常のセグメントです)。

このようなパケットにはユーザーアプリケーションに配信するデータが含まれていないためrecv()、返されることはありませんrecv()。実際のデータが到着するまでブロックを続けます。0を返す場合recv()は、もう一方の端が接続の側を閉じており、これ以上データを送信しないことを明確に示しています。

TCPはストリーム指向であることに注意してください。単一の呼び出しによって返されるデータと単一のTCPセグメント内のデータの間に1対1のマッピングはありません。recv()1回のrecv()呼び出しで、複数のTCPセグメントと重複するデータのブロックが返される場合があり、1回のTCPセグメントのデータが複数のrecv()呼び出しで返される場合があります。TCPセグメント間の境界は、BSDソケットAPIを使用するアプリケーションには表示されません。このような境界が必要な場合は、TCPストリーム内でアプリケーション層プロトコルを使用して実装するか、UDPなどのデータグラム指向のプロトコルを使用する必要があります。

于 2010-07-08T01:15:45.790 に答える
3

そうです、POSIXによると、recvが返された場合0、接続はピアによって正しくシャットダウンされます。

誰かがゼロサイズのペイロードでTCPパケットを送信することに成功した場合、OSは、そのソケットでのシステムコールでブロックされているプロセスにデータを返す必要はありません。recv

TCPペイロードは、単一のシステムコール中に返される必要のあるデータグラムのシーケンスではなく、OSによってランダムにスライスされる可能性のある連続ストリームを形成することに注意してください。

于 2010-07-07T22:00:41.147 に答える