両方ともNagleのアルゴリズムを無効にすることを理解しました。
それらのそれぞれを使用すべき/使用すべきでないのはいつですか?
まず第一に、両方ともNagleのアルゴリズムを無効にしません。
Nagleのアルゴリズムは、有線の小さなネットワークパケットの数を減らすためのものです。アルゴリズムは、データが制限(通常はMSS)よりも小さい場合、以前に送信されたパケットのACKを受信するまで待機し、その間にユーザーからデータを蓄積します。次に、蓄積されたデータを送信します。
if [ data > MSS ]
send(data)
else
wait until ACK for previously sent data and accumulate data in send buffer (data)
And after receiving the ACK send(data)
これは、telnetなどのアプリケーションで役立ちます。ただし、ACKを待機すると、ストリーミングデータを送信する際の遅延が増加する場合があります。さらに、受信者が「遅延ACKポリシー」を実装すると、一時的なデッドロック状態が発生します。このような場合、Nagleのアルゴリズムを無効にする方が良いオプションです。
したがって、TCP_NODELAYはNagleのアルゴリズムを無効にするために使用されます。
TCP_CORKは積極的にデータを蓄積します。ソケットでTCP_CORKが有効になっている場合、バッファが一定の制限に達するまでデータを送信しません。 Nagleのアルゴリズムと同様に、ユーザーからのデータも累積しますが、ACKを受信するまでではなく、バッファーが一定の制限に達するまでです。これは、複数のデータブロックを送信するときに役立ちます。ただし、TCP_CORKを使用するときは注意が必要です。
2.6カーネルまで、これらのオプションは両方とも相互に排他的です。しかし、後のカーネルでは、両方が共存できます。そのような場合、TCP_CORKがより優先されます。
参照:
_TCP_NODELAY
_
Nagleのアルゴリズムを無効にして、TCP/IPネットワークを改善し、以前に送信したデータの確認応答を受信して蓄積パケットを送信するまで待機することにより、パケット数を減らします。
// tcp(7)マニュアルから:
_TCP_CORK
_(または_TCP_NOPUSH
_ FreeBSDの場合)
設定されている場合、部分的なフレームを送信しません。オプションが再びクリアされると、キューに入れられたすべての部分フレームが送信されます。これは、sendfile(2)
を呼び出す前にヘッダーを追加する場合、またはスループットの最適化に役立ちます。現在実装されているように、出力が_TCP_CORK
_によってコルクされる時間には** 200ミリ秒の上限があります。 この上限に達すると、キューに入れられたデータが自動的に送信されます。このオプションは、Linux 2.5.71以降のみ_TCP_NODELAY
_と組み合わせることができます。このオプションは、移植性を目的としたコードでは使用しないでください。
これは最適化であり、他の最適化と同様です。
基本的に、目的は、sendfile()およびそのフレンドとともに、単一のフレームを使用できる複数のフレームを送信する必要を回避することです。
たとえば、Webサーバーでは、ヘッダーに続いてファイルの内容を送信します。ヘッダーはメモリ内で組み立てられ、ファイルはカーネルによって直接送信されます。 TCP_CORKを使用すると、TCP_NODELAYを使用してもヘッダーとファイルの先頭を単一のフレームで送信できます。そうしないと、最初のチャンクがすぐに送信されてしまいます。
TCP_CORKはTCP_NODELAYの反対です。前者はパケット蓄積遅延を強制します。後者は無効にします。