RFC793 ドキュメントの SYN フラグを持つプロセス パケットはデータを伝送できません。つまり、3 ウェイ ハンドシェイクの最初の 2 つはデータを伝送できません (論理的に言えば、接続はまだ確立されていないため、データを伝送するのは少し無理があるようです)。重要な点は、3 回目のハンドシェイクでデータを伝送できるかどうかです。 まず結論を述べます。TCP プロトコルの 3 ウェイ ハンドシェイク プロセスにおける接続を確立するための 3 番目のハンドシェイクにより、データの伝送が可能になります。 上記の TCP 状態変化図の接続確立部分を参照して、RFC793 ドキュメントの内容を見てみましょう。 RFC793 ドキュメントには、次の内容が記載されています (重要でない部分は省略)。 重要な点は、「送信のためにキューに入れられたデータまたは制御が含まれる場合があります」という文です。これは、3 番目のハンドシェイクの ACK パケットがデータを伝送できることを標準が示していることを意味します。 まず、3 回目のハンドシェイクのパケットは、接続イニシエーター (以下、クライアント) からポート リスナー (以下、サーバー) に送信されるので、接続が SYN-RECV (図では SYN_RECEIVED) 状態のときにパケットを受信した後、カーネル プロトコル スタックの処理プロセスを見つけるだけで済みます。少し調べたところ、net\ipv4 ディレクトリの tcp_input.c ファイルの tcp_rcv_state_process 関数がこの処理を処理することがわかりました。図に示すように: この関数は実際には TCP ステート マシンであり、TCP 接続がさまざまな状態にあるときに受信したデータ パケットの処理を処理するために使用されます。ここには並列の switch 文がいくつかあります。関数が非常に長いため、階層関係を誤読しやすくなります。次の図は、考慮する必要のないコードを簡略化した後の SYN-RECV 状態の処理を示しています。 2 つの switch ステートメントが並列であることに注意することが重要です。したがって、TCP_SYN_RECV 状態が合法かつ標準化された双方向ハンドシェイク パケットを受信すると、ソケット状態は直ちに TCP_ESTABLISHED 状態に設定されます。実行が次の TCP_ESTABLISHED 状態ケースに達すると、そこに含まれるデータ (存在する場合) の処理が続行されます。 上記は、クライアントから送信された 3 番目のハンドシェイクの ACK にデータが含まれている場合、サーバーはそれを正常に処理できることを示しています。では、クライアント側はどうでしょうか? SYN-SEND 状態のときにクライアントが 3 番目の ACK パケットを送信する方法を見てみましょう。図に示すように: tcp_rcv_synsent_state_process 関数の実装は比較的長いので、最終的な重要なポイントは次のとおりです。 一目見て分かりますよね?条件が満たされない場合は、別の ACK パケットで直接応答します。条件が満たされた場合は、inet_csk_reset_xmit_timer 関数を使用して、短時間待機するタイマーを設定します。この期間中にデータがある場合は、データとともに ACK が送信されますが、ACK で返信するデータはありません。 これまでの疑問は解決されました。 条件 1: sk->sk_write_pending != 0 この値はデフォルトで 0 になりますが、0 以外になる原因は何でしょうか?答えは、プロトコル スタックのデータ送信機能が ESTABLISHED ではないソケット ステータスに遭遇すると、この変数に対して ++ 操作を実行し、しばらく待ってからデータの送信を試行するということです。写真をご覧ください: net/core/stream.c の sk_stream_wait_connect 関数は次の処理を実行します。 sk->sk_write_pending が増加し、ソケット接続が ESTABLISHED 状態に達した後にデータが送信されます。それは明らかに説明しています。 Linux ソケットのデフォルトの動作モードはブロッキングです。つまり、クライアントの接続呼び出しはデフォルトでブロックされ、3 ウェイ ハンドシェイク プロセスが完了するかエラーが発生するまで戻りません。次に、ブロッキング ソケットで完全に実装され、デフォルトのソケット パラメータを変更しないコマンド ライン アプレットである nc は、データを送信する前に connect が成功または失敗を返すのを待ちます。これが、3 番目のハンドシェイクのパケットでデータをキャプチャできない理由です。 次に、非ブロッキング ソケットを設定し、接続後すぐにデータを送信します。接続プロセスがすぐに成功しない場合は、データを含む 3 番目のハンドシェイク パケットが表示される可能性があります。ただし、オープンソース ネットワーク ライブラリが非ブロッキング ソケットであっても、ソケットの書き込み可能なイベントを監視し、接続が成功したことを確認した後にのみデータを書き込みます。このわずかなパフォーマンス向上を節約することは、安全で信頼性の高いコードを持つことほど価値がありません。 条件2: icsk->icsk_accept_queue.rskq_defer_accept != 0 この状態は非常に奇妙です。defer_accept は、受け入れを延期するために使用されるソケット オプションです。実際には、最初のデータが受信された後にのみ接続が作成されます。 tcp_defer_accept オプションは通常サーバー側で使用され、ソケットの SYN キューと ACCEPT キューに影響します。デフォルトで設定されていない場合は、3 ウェイ ハンドシェイクが完了した後、ソケットは受け入れキューに入り、アプリケーション層が関連する接続を感知して ACCEPT します。 tcp_defer_accept が設定されている場合、3 ウェイ ハンドシェイクが完了し、ソケットは ACCEPT キューに入らず、データが実際に送信されて ACCEPT キューに入れられるまで、SYN キューに直接留まります (長さの制限があり、長さが制限を超えるとカーネルは新しい接続を拒否します)。このパラメータを設定するサーバーは、受け入れ後すぐに読み取ることができるため、データが存在する必要があり、システムコールも節約されます。 SYN キューは、SYN_RECV 状態のソケットを格納します。長さは、net.ipv4.tcp_max_syn_backlog パラメータによって制御されます。受け入れキューは、listen が呼び出されたときに backlog パラメータによって設定されます。カーネルのハード制限は net.core.somaxconn によって制限されます。つまり、実際の値は min(backlog,somaxconn) によって決定されます。 興味深いのは、クライアントが最初にポートと IP にバインドし、setsockopt(TCP_DEFER_ACCEPT) を設定してからサーバーに接続すると、rskq_defer_accept=1 が表示されることです。この時点で、カーネルは ACK パケットに応答する前にデータを待機するためのタイマーを設定します。個人的にはこれをやったことはありません。パフォーマンスを向上させるために空の ACK パケットの送信を減らすだけでしょうか?クラスメイトで知っている人がいたら教えてください。よろしくお願いします。 条件3: icsk->icsk_ack.pingpong != 0 pingpong 属性は、実際には現在のリンクがインタラクティブ データ ストリームであるかどうかを示すソケット オプションです。値が 1 の場合、インタラクティブ データ ストリームであり、遅延確認メカニズムが使用されることを示します。 以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
<<: Vue3 (V) HTTPライブラリaxiosの統合の詳細
>>: HTML テーブル マークアップ チュートリアル (28): セルの境界線の色属性 BORDERCOLOR
目次範囲グローバルスコープ関数のスコープもし、スイッチ、のために、その間ブロックスコープスコープチェ...
目次1. クロージャとは何ですか? 2. クロージャの役割2.1) メモリ2.2) プライベート変数...
6つの効果実装コードhtml <h1>CSS 境界遷移</h1> <セ...
序文Linux でショートカットを作成すると、アプリケーションをより速く開くことができます。ここで、...
序文コンピュータの数値は浮動小数点であるため、計算プロセス中に取得されるデータは通常正確ではなく、そ...
1. イメージをプルするまず、次のコマンドを実行して、イメージをローカル コンピューターにダウンロー...
DataGrid コントロールの DataSource プロパティがデザイン時に設定されている場合、...
<スタイル タイプ="text/css">コードをコピーコードは次の...
Sysbench は、MySQL データベース ストレージ エンジン InnoDB のディスク I/...
Mac システムには PHP と Apache が付属していますが、必要なバージョンではない場合があ...
1. コマンドの紹介stat コマンドは、ファイルまたはファイル システムに関する詳細情報を表示する...
目次一般的な圧縮形式: gz .bz2 .xz .zip一般的に使用されるアーカイブは圧縮を必要とす...
HTMLとは何ですか?簡単に言えば、HTML は Web ページを作成するために使用されます。とて...
MySQLでは判定記号がよく使われますが、等しくない記号はもっと一般的に使われます。次の3つの等しく...
/************************ * Linux メモリ管理 *********...