第8章 ソケット
ソケット は双方向のデータ転送メカニズムです。これらは、2 つのプロセス間でデータを転送するために使用されます。2 つのプロセスは、Unix-domain またはループバックソケットと同じシステム、またはネットワークソケットとして異なるシステムで実行できます。
Red Hat Enterprise Linux for Real Time システムでソケットを使用する特別なオプションや制限はありません。
8.1. ソケットオプション
Red Hat Enterprise Linux for Real Time アプリケーションに関連する 2 つのソケットオプション
TCP_NODELAY
および TCP_CORK
があります。
TCP_NODELAY
TCP は最も一般的なトランスポートプロトコルです。つまり、多くの異なるニーズに対応するために使用されます。新しいアプリケーションおよびハードウェア機能が開発され、カーネルアーキテクチャーの最適化が行われると、TCP は変更を効果的に処理するために新しいヒューリスティックを導入する必要がありました。
このヒューリスティックにより、プログラムが不安定になる可能性があります。動作は基盤となるオペレーティングシステムのコンポーネントが変更されるため、注意して処理する必要があります。
TCP のヒューリスティックな動作の 1 つの例は、小さいバッファーが遅延することです。これにより、1 つのネットワークパケットとして送信できます。通常、これは正常に機能しますが、レイテンシーを作成することもできます。Red Hat Enterprise Linux for Real Time アプリケーションでは、
TCP_NODELAY
は、この動作をオフにするのに指定できるソケットオプションです。以下の機能を使用すると、setsockopt
ソケット API で有効にできます。
int one = 1; setsockopt(descriptor, SOL_TCP, TCP_NODELAY, &one, sizeof(one));
このオプションを効果的に使用するには、TCP はこのバッファーを個別のパケットとして送信するため、バッファーの小さい書き込みは回避する必要があります。また、
TCP_NODELAY
はその他の最適化ヒューリスティックと対話でき、全体的なパフォーマンスが低下します。
アプリケーションに論理的に関連し、1 つのパケットとして送信する必要があるバッファーが複数ある場合は、送信前に連続したパケットを構築することで、レイテンシーとパフォーマンスが向上します。その後、パケットは
TCP_NODELAY
が有効なソケットを使用して送信できます。
メモリーバッファーが論理的に関連付けられていても、まだ連続していない場合は、それらを使用して I/O ベクトルを構築します。その後、
TCP_NODELAY
を有効にしたソケットで writev
を使用してカーネルに渡すことができます。
TCP_CORK
同様の方法で機能する別の TCP ソケットオプションは、TCP_CORK
です。有効にすると、アプリケーションが cork を削除されるまで TCP パケットがすべて遅延し、保存されたパケットが送信されます。これにより、アプリケーションはカーネル領域にパケットを構築できます。これは、異なるライブラリーを使用して層の抽象化を提供する場合に便利です。
以下の関数を使用すると、
TCP_CORK
オプションを有効にできます。
int one = 1; setsockopt(descriptor, SOL_TCP, TCP_CORK, &one, sizeof(one));
多くの場合、
TCP_CORK
の有効化は、corking the socket
と呼ばれます。
cork の削除タイミングをカーネルが特定できない場合は、関数を使用して手動で削除できます。
int zero = 0; setsockopt(descriptor, SOL_TCP, TCP_CORK, &zero, sizeof(zero));ソケットのコードが解除されると、TCP は、アプリケーションからの追加のパケットを待たずに累積された論理パッケージを即座に送信します。
例8.1 TCP_NODELAY
および TCP_CORK
の使用
この例では、
TCP_NODELAY
と TCP_CORK
による、アプリケーションのパフォーマンスへの影響を示しています。
サーバーは 30 バイトのパケットを待機した後、2 バイトパケットを応答で送信します。はじめに、TCP ポートと処理するパケット数を定義します。この例では、これは 10,000 パケットです。
~]$ ./tcp_nodelay_server 5001 10000
サーバーにはソケットオプションを設定する必要はありません。
クライアントが引数を指定せずに実行すると、デフォルトのソケットオプションが使用されます。
TCP_NODELAY
ソケットオプションを有効にするには、no_delay
オプションを指定します。TCP_CORK
を有効にする場合は、cork
オプションを指定します。すべてのケースで 15 パケットが送信され、それぞれ 2 バイトの送信とサーバーからの応答を待機します。
この例では、ループバックインターフェースを使用して、3 つの変動を示しています。
最初のバリアントでは、
TCP_NODELAY
も TCP_CORK
も使用されません。これはベースラインの測定です。TCP のコアレッシングは書き込みを行い、アプリケーションがネットワークパケットに最適に適合できる以上のデータがあるかどうかを確認する必要があります。
~]$ ./tcp_nodelay_client localhost 5001 10000
10000 packets of 30 bytes sent in 400129.781250 ms: 0.749757 bytes/ms
2 つ目のバリエーションでは
TCP_NODELAY
のみを使用します。TCP は小さなパケットを結合しないように指示されますが、バッファーを即座に送信するよう指示されます。これによりパフォーマンスが大幅に改善されますが、各論理パケットに多数のネットワークパケットが作成されます。
~]$ ./tcp_nodelay_client localhost 5001 10000 no_delay
10000 packets of 30 bytes sent in 1649.771240 ms: 181.843399 bytes/ms using TCP_NODELAY
3 つ目のバリアント
TCP_CORK
は使用します。これは、同じ数の論理パケットを送信するのに必要な時間を 2 倍にします。これは、TCP がバッファーに論理パケット全体を結合し、ネットワークパケット全体を送信するためです。
~]$ ./tcp_nodelay_client localhost 5001 10000 cork
10000 packets of 30 bytes sent in 850.796448 ms: 352.610779 bytes/ms using TCP_CORK
このシナリオでは、
TCP_CORK
が最適な手法です。これにより、アプリケーションはパケットが終了していることを正確に伝えることができ、遅延なく送信する必要があります。プログラムを開発する際にファイルから一括データを送信する必要がある場合は、TCP_CORK
を sendfile
とともに使用することを考慮してください。
注記
詳細やその他文書は、以下の man ページとサンプルアプリケーションが、本セクションの情報に関連しています。
- sendfile(2)
- 「TCP nagle サンプルアプリケーション」 (C で書かれた両方のソケットオプションのアプリケーションの例)。ダウンロードするには、以下のリンクから右クリックして保存します。