ソケットに何度も素早く連続して書き込む場合(POSIX関数を使用write
)、通常私が書き込むすべてのデータは単一のTCPパケットで送信されます。書くのがあまり書かれていない限り、書く間に長すぎるのを待たない限り。
カーネルは私がソケットに書き込むデータをバッファリングし、定期的にパケットを送信しますか?それともlibcはこれを処理しますか?カーネルはパケットを送信する前にどのくらい待ちますか?ほぼ空のパケットがすぐに送信されるように要求できますか? UDPまたは他のプロトコルは異なる方法で処理されますか?
これらすべてがどのように機能するかを知りたいのですが、そのトピックに関する情報を見つけるのが困難です。
答え1
オペレーティングシステムは、送信前に短期バッファリングを実行できます。たとえば、Linuxのマニュアルページtcp(7)
TCP_NODELAY
このオプションを無効にするオプションについて説明します(参照:setsockopt(2)
):
TCP_NODELAY
設定されている場合、Nagleアルゴリズムを無効にします。これは、データ量が少なくても、データセグメントが常にできるだけ早く送信されることを意味する。設定しないと、十分な量が送信されるまでデータがバッファリングされるため、小さなデータパケットが頻繁に送信されるのを防ぎ、ネットワークの利用率が低下します。このオプションはによって上書きされます。ただし、このオプションを設定すると、現在設定されていても保留TCP_CORK
中の出力が明示的にフラッシュされます。TCP_CORK
Nagelのアルゴリズム実際のバッファリングアルゴリズムです。ナビゲーションパスに正しく従うRFC 1122現在有効な定義のようです。
これはlibcではなくカーネルです。 Cライブラリはstdioストリーム(FILE *
)をバッファリングしますが、カーネルにwrite()
直接移動します。send()
UDPでは、データグラムのサイズが非常に重要であり、上位層に表示されるため、同様の破損は不可能です。