私はTCPを教えており、ウィンドウサイズに達したときにのみACKが送信されると誤って教えられた人によく遭遇します。本当じゃない。(本当にわかりやすくするために、私もよく知る前に、これも間違って教えたので、間違いを完全に理解しました)。
注、レシーバ/センダを使用して説明しますが、TCPは双方向であり、両方のパーティがウィンドウサイズを維持することに注意してください。
ウィンドウサイズ(Receiverが設定)は、Senderが強制的に停止して確認応答を待たずに送信できるバイト数のハード制限です。
ウィンドウサイズは、レシーバーがACKを送信する頻度を決定しません。もともと、TCPプロトコルは、各セグメントが受信された後に確認応答を送信することを要求していました。その後、TCPが最適化され、ReceiverがACKをスキップして、1つおき(またはそれ以上)のパケットごとにACK通知を送信できるようになりました。
TCPの目標は、Senderが継続的にACKを受信するため、遅延や中断なしに継続的にパケットを送信することです。これにより、「送信中のバイト」の数は常にウィンドウサイズよりも小さくなります。SenderがACKを受信せずにウィンドウサイズに等しいバイト数を送信した場合、送信を一時停止して待機する必要があります。
これらすべてにおいて考慮すべき重要なことは、往復時間です。多くの場合、wiresharkでTCPを研究しているときは、TCP会話で1つのパーティの視点しか見られないため、RTTの効果を推測または実際に「見る」ことが難しくなります。RTTの効果を説明するために、これらの2つのキャプチャを見てください。彼らは両方とも同じ会話、HTTP経由で2メガバイトのファイルのダウンロードをキャプチャしているが、1から提示されたクライアントの視点、およびその他から提示されたサーバーの視点。
注:Wireshark機能をオフにすると、TCPを分析しやすくなります。「サブディセクタがTCPストリームを再構成できるようにします」
サーバー側のキャプチャ(ファイルの送信者)からの通知では、サーバーは8つのフルサイズのパケットを連続して送信し(packet#の6-13)、packet#14の最初のACKを受信します。そのACK、クライアントの確認がPacket#7で送信されたセグメントに対するものであることに注意してください。そして、クライアントがパケット20で送信したACKは、Packet#9で送信されたセグメントからのものです。
クライアントが他のすべてのパケットを実際に確認している方法を確認します。しかし、それは彼らが「後期」を認めているように思われます。しかし実際には、これは往復時間の影響にすぎません。Senderは、最初のセグメントがクライアントに到達し、クライアントのACKがサーバーに到達するのにかかる時間で7〜セグメントを送信できます。キャプチャをクライアントの観点から見ると、非常に「クリーン」に見えます。つまり、受信する2番目のパケットごとに、ACKを送信します。
また、Packet#23で何が起こるかにも注目してください。「転送中のバイト数」がウィンドウサイズに達したため、サーバーは送信可能なすべてを送信したため、送信を強制的に停止します。次のACKが到着するまで。ACKは、受信した他のすべてのセグメントで受信されるためです。各ACKにより、送信者はウィンドウが再びいっぱいになる前に、2つの新しいセグメントを再度送信でき、サーバーは再び一時停止します。これは、クライアント(Recever)がウィンドウサイズを大幅に増やし、サーバー(送信者)が抑制されずにデータの送信を再開できるようにするPacket#51まで発生します。少なくとも、新しいウィンドウがいっぱいになるPacket#175まで。