コンピュータネットワークのまとめ#
一、アーキテクチャ#
アプリケーション層
:アプリケーション層プロトコルは、アプリケーションプロセス間の通信と相互作用のルールを定義し、特定のアプリケーションにデータ転送サービスを提供します。例えば、HTTP、DNS など。データ単位はメッセージです。トランスポート層
:トランスポート層の任務は、2 台のホスト間のプロセス間通信に一般的なデータ転送サービスを提供することです(TCP または UDP)。ネットワーク層
:トランスポート層で生成されたメッセージセグメントまたはユーザーデータグラムをパケットまたはフレームにカプセル化して送信します。データリンク層
:ネットワーク層から渡された IP データグラムをフレームに組み立て、隣接ノード間のリンクで送信します。物理層
:物理メディアを使用してビット形式でデータを送信します。
物理層チャネル多重化技術#
基本概念#
チャネル、特定の方向に情報を送信するメディアを含みます。
- 一方向チャネル:一方が送信し、一方が受信する、
単方向
- 双方向交互チャネル:双方がメッセージを送信できますが、同時には行えません、
半二重
- 双方向同時チャネル:双方が同時に情報を送信できます、
全二重
多重化とは、チャネルの共有を意味し、一般的なチャネル多重化技術には、周波数分割多重化、時間分割多重化、統計的時間分割多重化があります。マルチプレクサとデマルチプレクサを使用して信号の多重化と分配を行います。
チャネル多重化技術#
1. 周波数分割多重化 FDM
ユーザーは同じ時間内に異なる周波数帯域を占有して同じチャネルを多重化します。
2. 時間分割多重化 TDM
時間を同じ時間分割多重化フレーム TDM に分割し、異なる時間に同じ周波数帯域を占有します。
3. 統計的時間分割多重化 STDM
改良された時間分割多重化で、必要に応じて動的にタイムスロットを割り当てます。固定割り当てではなく、(タイムスロット数がハブに接続されているユーザー数より少ないため、毎回送信される STDM フレーム内のパケットは満杯です)。
4. 波長分割多重化 WDM
光の周波数分割多重化で、光通信技術で利用されます。
5. コード分割多重化 CDM
各ユーザーは同じ時間に同じ周波数帯域を使用して通信しますが、各ユーザーは選択された異なるコードを使用するため、ユーザー間で独立した通信が可能です。
データリンク層#
データリンク層の主な機能:
- リンク管理
- フレーム同期
- フロー制御
- エラー制御
- データと制御情報の区別
- 透過的伝送
- アドレッシング
データリンク層の 3 つの基本的な問題:フレームへのカプセル化
、透過的伝送
、エラー検出
。
フレームへのカプセル化#
IP データグラムの前後にヘッダーとトレーラーを追加してフレームを構成し、受信側が物理層のビットストリーム内でフレームの開始と終了を知ることができるようにします。つまり、フレーム境界を行います。
さらに、ヘッダーとトレーラーには多くの制御情報も追加され、データリンク層プロトコルは送信可能なフレームのデータ部分の長さの上限を規定します。最大伝送単位 ——MTU
透過的伝送#
透過的伝送の概念は、データリンク層で伝送されるデータがデータリンク層で何の阻害も受けず、受信側が受け取ったデータと送信側が送信したデータに何の違いもないことを指します。つまり、データリンク層はその伝送データフレームに対して完全に透過的です。
バイトフィリング:
伝送中にデータ部分にフレーム境界記号が現れるのを防ぐため、受信側が受け取ったデータが早期に終了したと誤解しないように、制御文字の前にエスケープ文字を挿入します。受信側のデータリンク層は挿入されたエスケープ文字を削除します。
ゼロビットフィリング法:
5 つの連続した 1 が見つかった場合、すぐに 0 を挿入し、6 つの連続した 1 が現れないようにします。
エラー検出#
エラー検出は、伝送中に発生するビットエラーを指します。
** 誤り率:** 一定の時間内に伝送エラーのビットが伝送総数に占める比率。
現在、データリンク層で採用されているエラー検出方式は循環冗長検査です。
注:
データリンク層ではビットエラーがないことを保証しますが、伝送エラーは保証しません。伝送エラーにはフレームの喪失
、フレームの重複
、フレームの順序の逆転
などが含まれます。
二、IP アドレス#
概要#
コンピュータがネットワーク通信を実現するためには、迅速に位置を特定するためのネットワークアドレスが必要です。IP アドレスは、コンピュータがネットワーク内での唯一の身分 ID であり、現実世界の宅配便の配送に具体的な住宅アドレスが必要であるのと同じです。
IP アドレス = ネットワークアドレス + ホストアドレス(別名:ホスト番号とネットワーク番号の組み合わせ)
ネットワークセグメントの分割#
A クラスアドレス:0 で始まり、最初のバイトの範囲:0 - 127(1.0.0.0 - 126.255.255.255
);
B クラスアドレス:10 で始まり、最初のバイトの範囲:128 - 191(128.0.0.0 - 191.255.255.255
);
C クラスアドレス:110 で始まり、最初のバイトの範囲:192 - 223(192.0.0.0 - 223.255.255.255
);
インターネット上の予約アドレスは内部のプライベート使用のために:10.0.0.0 - 10.255.255.255
、172.16.0.0 - 172.31.255.255
、192.168.0.0 - 192.168.255.255
。
サブネットマスク#
-
サブネットを分割する際、元々ホスト番号に属する一部をネットワーク番号に分割します。どの部分がネットワーク番号で、どの部分がホスト番号であるかを区別するために、サブネットマスクを使用する必要があります。
-
サブネットマスクは単独では存在できず、IP アドレスと一緒に使用する必要があります。
-
サブネットマスクの唯一の役割は、特定の IP アドレスをネットワークアドレスとホストアドレスの 2 つの部分に分割することです。
サブネットマスクの計算#
サブネット数を使用してサブネットマスクを計算#
計算ルール:
-
サブネット数を二進数に変換して表現します。
-
その二進数のビット数を取得し、N とします。
-
その IP アドレスのクラスのサブネットマスクを取得し、ホストアドレス部分の最初の N ビットを 1 に設定します。これにより、その IP アドレスのサブネットマスクが得られます。
B クラス IP アドレス 168.195.0.0 を 27 個のサブネットに分割する場合:
-
27=11011
-
この二進数は 5 ビットで、N = 5
-
B クラスアドレスのサブネットマスク 255.255.0.0 のホストアドレスの最初の 5 ビットを 1 に設定し、255.255.248.0 が 27 個のサブネットに分割された B クラス IP アドレス 168.195.0.0 のサブネットマスクとなります。
ホスト数を使用してサブネットマスクを計算#
計算ルール:
-
ホスト数を二進数に変換して表現します。
-
ホスト数が 254 以下の場合(予約された 2 つの IP アドレスを除外)、そのホストの二進数のビット数を取得し、N とします。ここで N<8 です。254 を超える場合、N>8 となり、ホストアドレスは 8 ビット以上を占有します。
-
255.255.255.255 を使用して、そのクラスの IP アドレスのホストアドレスビットをすべて 1 に設定し、後ろから前に向かって N ビットをすべて 0 に設定します。これがサブネットマスクの値となります。
B クラス IP アドレス 168.195.0.0 をいくつかのサブネットに分割し、各サブネット内に 700 台のホストがある場合:
-
700=1010111100
-
この二進数は 10 ビットで、N = 10
-
B クラスアドレスのサブネットマスク 255.255.0.0 のホストアドレスをすべて 1 に設定し、255.255.255.255 を得てから、後ろから前に向かって後の 10 ビットを 0 に設定します。つまり、11111111.11111111.11111100.00000000 となり、255.255.252.0 が 700 台のホストに分割された B クラス IP アドレス 168.195.0.0 のサブネットマスクとなります。
三、UDP#
概要#
- ユーザーデータグラムプロトコル UDP は、IP データグラムサービスに多重化と分配機能、エラー検出機能を追加したものです。
接続指向でないメッセージ
、信頼性のない伝送
の特徴があります。 - UDP はアプリケーション層からのデータにヘッダーを追加し、特別な処理を行った後、ネットワーク層に渡します。
- ネットワーク層から受け取ったユーザーデータグラムのヘッダーを取り外した後、元のままアプリケーション層に渡します。
UDP ヘッダー形式#
UDP ヘッダーのフィールドは非常にシンプルで、4 つのフィールドで構成され、各フィールドの長さは 2 バイトで、合計 8 バイトです。
- ソースポート番号:相手に返信を求める場合に選択し、必要ない場合は全 0 にできます。
- 宛先ポート番号:これは最終的にメッセージを配信する際に必ず使用されます。さもなければ、データは誰に渡されるのでしょうか?
- 長さ:UDP の長さで、最小値は 8 バイトで、ヘッダーのみです。
- チェックサム:ユーザーデータグラムが伝送中にエラーがないかを検出し、エラーがあれば破棄します。
伝送中に受信側 UDP が受け取ったメッセージの宛先ポートが存在しない場合、直接破棄し、インターネット制御メッセージプロトコル ICMP が送信側に「ポート到達不能」エラーメッセージを送信します。
循環冗長検査法については、詳しくは:CRC(循環冗長検査コード)概要と実装解析を参照してください。
四、TCP#
TCP プロトコルは、トランスポート層の主要なプロトコルの 1 つであり、接続指向で、エンドツーエンドで、信頼性のある全二重通信を提供し、バイトストリーム指向のデータ伝送プロトコルです。
TCP セグメント#
TCP はバイトストリーム指向ですが、TCP が伝送するデータ単位はセグメントです。TCP セグメントはTCPヘッダー
とデータ部分
に分かれ、TCP セグメントヘッダーの最初の20バイト
は固定されており、後ろに 4n バイトが必要に応じて動的に追加されます。最大長は 40 バイトです。
-
ソースポートと宛先ポート
はそれぞれ 2 バイトを占め、TCP の分配機能もポートを通じて実現されます。 -
シーケンス番号
は 4 バイトを占め、範囲は [0,232] です。TCP はバイトストリーム指向であり、各バイトは順番に番号が付けられます。例えば、あるセグメントのシーケンス番号フィールドが 201 で、データ長が 100 の場合、最初のデータのシーケンス番号は 201 で、最後のデータは 300 です。最大範囲に達すると、0 から再スタートします。 -
確認番号
は 4 バイトを占め、相手が次に受け取るべきセグメントの最初のバイトのシーケンス番号を期待しています。確認番号 = N の場合、シーケンス番号 N 以前のすべてのデータが正しく受信されたことを示します。 -
データオフセット
は 4 ビットを占め、セグメントのデータ部分の開始位置を示し、全体のセグメントの開始位置からの距離を示します。間接的にヘッダーの長さを示します。 -
予約
は 6 ビットを占め、現在は 0 です。 -
URG(緊急)
は、URG=1 の場合、緊急ポインタフィールドが有効であり、このセグメントには緊急データが含まれており、できるだけ早く送信されるべきです。 -
確認番号(Acknowledgement Number)
は ACK=1 の場合のみ有効であり、接続が確立された後、すべてのセグメントの ACK は 1 になります。 -
PSH(プッシュ)
受信側が PSH=1 のセグメントを受信すると、できるだけ早くアプリケーションに配信され、全体のバッファが満杯になるのを待たずに配信されます。実際にはあまり使用されません。 -
RST(リセット)
RST=1 の場合、TCP 接続に深刻なエラーが発生し、接続を閉じて再接続する必要があります。 -
SYN(同期)
接続を確立する際にシーケンス番号を同期するために使用されます。SYN=1、ACK=0 の場合、接続要求のセグメントを示します。SYN=1、ACK=1 の場合、相手が接続に同意したことを示します。TCP 接続の確立に使用されます。 -
FIN(終了)
接続ウィンドウを解放するために使用されます。FIN=1 の場合、このセグメントの送信者はもはやデータを送信せず、一方向の接続を解放することを要求します。TCP 接続の切断に使用されます。 -
ウィンドウ
は 2 バイトを占め、送信者自身の受信ウィンドウを示し、ウィンドウ値は相手に許可されるデータ量を知らせるために使用されます。 -
チェックサム
は 2 バイトを占め、チェックサムフィールドの範囲にはヘッダーとデータ部分が含まれます。 -
緊急ポインタ
は 2 バイトを占め、URG=1 の場合、緊急ポインタはこのセグメント内の緊急データのバイト数(緊急バイト数の後は通常のバイト)を示します。 -
オプション
の長さは可変で、最大 40 バイトに達することがあります。例えば、最大セグメント長 MSS。MSS はデータ部分の長さを指し、全体の TCP セグメントの長さではなく、MSS のデフォルトは 536 バイトです。ウィンドウの拡張、タイムスタンプオプションなどがあります。
三回のハンドシェイク#
-
最初の:クライアントが接続要求メッセージをサーバーに送信します。この際、SYN=1、seq=x(クライアントの初期シーケンス番号を示す)です。送信後、SYN_END 状態に入ります。
-
二回目:サーバーがメッセージを受信した後、確認メッセージを返します。この際、ACK=1、ack=x+1 で、クライアントの確認が必要なため、メッセージには SYN=1、seq=y の情報も含まれます。送信後、SYN_RCVD 状態に入ります。
-
三回目:クライアントがメッセージを受信した後、確認メッセージを送信します。この際、ACK=1、ack=y+1 です。クライアントは ESTABLISHED 状態に入り、サーバーがメッセージを受信した後、ESTABLISHED 状態に入ります。これで接続が確立されました。
三回のハンドシェイクの理由
リソースの無駄遣いを避けるためです。もし二回目のハンドシェイクの際にネットワークの遅延により確認パケットがクライアントに届かない場合、クライアントは最初のハンドシェイクが失敗したと考え、再度接続要求を送信します。サーバーがそれを受け取ると、再度確認パケットを送信します。この場合、サーバーはすでに 2 回接続を作成し、2 つのクライアントからデータを送信するのを待っていることになりますが、実際には 1 つのクライアントしかデータを送信しないため、リソースの無駄遣いが発生します。
四回のフィニッシュ#
四回のフィニッシュは、クライアントとサーバーがそれぞれ接続終了要求メッセージを送信し、双方が互いの要求に応答することを指します。
-
最初のフィニッシュ:クライアントが FIN=1、seq=x のパケットをサーバーに送信し、自分には送信するデータがないことを示し、一方向の接続を閉じることを要求します。送信後、クライアントは FIN_WAIT_1 状態に入ります。
-
二回目のフィニッシュ:サーバーが要求パケットを受信した後、ACK=1、ack=x+1 の確認パケットを返し、接続を切断することを確認します。サーバーは CLOSE_WAIT 状態に入ります。クライアントはこのパケットを受信した後、FIN_WAIT_2 状態に入ります。この時点でクライアントからサーバーへのデータ接続は切断されています。
-
三回目のフィニッシュ:サーバーが FIN=1、seq=y のパケットをクライアントに送信し、自分にはクライアントに送信するデータがないことを示します。送信後、LAST_ACK 状態に入り、クライアントの確認パケットを待ちます。
-
四回目のフィニッシュ:クライアントが要求パケットを受信した後、ACK=1、ack=y+1 の確認パケットをサーバーに送信し、TIME_WAIT 状態に入ります。再送信の可能性があります。サーバーが確認パケットを受信した後、CLOSED 状態に入り、サーバーからクライアントへの接続は切断されます。クライアントはしばらく待った後、CLOSED 状態に入ります。
注:
- デフォルトでは(ソケットオプションを変更しない限り)、close(または closesocket を呼び出すと、送信バッファにまだデータがある場合、TCP はデータを送信し続けます。
- FIN を送信しただけでは、この端はデータを送信できなくなることを示します(アプリケーション層は send を呼び出せなくなります)が、データを受信することはできます。
四回のフィニッシュの理由
TCP 接続は全二重であり、双方がデータを積極的に送信できるため、一方の切断は相手に通知する必要があり、後続の関連操作を行えるようにするためです。
TCP 伝送に基づくプロトコルには、FTP(ファイル転送プロトコル)
、Telnet(リモートログインプロトコル)
、SMTP(シンプルメール転送プロトコル)
、POP3(SMTPに対して、メールを受信するために使用)
、HTTPプロトコル
などがあります。
“三回のハンドシェイク、四回のフィニッシュ” の補足#
ISN#
三回のハンドシェイクの重要な機能は、クライアントとサーバーが ISN を交換し、相手がデータを受信する際にシーケンス番号に従ってデータを組み立てる方法を知ることです。
ISN が固定されている場合、攻撃者は後続の確認番号を簡単に推測できます。
ISN = M + F(localhost, localport, remotehost, remoteport)
M はタイマーで、4 ミリ秒ごとに 1 増加します。F はハッシュアルゴリズムで、ソース IP、宛先 IP、ソースポート、宛先ポートに基づいてランダムな値を生成します。ハッシュアルゴリズムが外部から簡単に推測されないようにする必要があります。
TIME_WAIT 状態の詳細#
TIME_WAIT 状態は2 * 最大セグメント生存時間(MSL)
に設定されます。TIME_WAIT 状態が存在する理由:
-
LAST_ACK 状態のソケットは、ACK メッセージを受信しないために FIN メッセージを再送信する可能性があるため、この TIME_WAIT 状態の役割は、失われた ACK メッセージを再送信するためのものです。
-
接続が切断されたことを確認します。切断されるこのリンクの後に、同じ IP アドレスとポートで新しい接続を確立しようとすると、古い接続の新しい要求と誤解される可能性があります(TCP セッションは【ソース IP、ソースポート、宛先 IP、宛先ポート】の 4 つの組み合わせによって一意に決定されます)。TCP セグメントの最大生存時間は MSL であり、2MSL の時間を保持することで、ネットワーク上の 2 つの伝送方向の未受信または遅延したセグメントが消失するか、ルーターによって破棄されることを保証できます。2MSL の時間後に新しい接続を確立すると、元の接続のアプリケーションデータを受信することは決してありません。このように、2MSL の長さの TIME_WAIT 状態を設定することで、新しい接続は元の接続のアプリケーションデータを受信することは決してありません。
シーケンス番号のラップアラウンド#
ISN がランダムであるため、シーケンス番号は容易に 2^31-1 を超えることがあります。TCP はパケットの損失や順序の逆転などの問題をシーケンス番号の大小比較に依存して判断しているため、いわゆる TCP シーケンス番号のラップアラウンド(sequence wraparound)問題が発生します。
半接続と全接続#
半接続キュー:
サーバーがクライアントから最初に SYN を受信すると、SYN_RCVD 状態になります。この時点で双方はまだ完全に接続を確立しておらず、サーバーはこの状態の接続要求をキューに入れます。このキューを半接続キューと呼びます。
全接続キュー:
三回のハンドシェイクを完了し、接続が確立されたものは全接続キューに入れられます。キューが満杯になると、パケットの損失が発生する可能性があります。
他の例として、SYNフラッド攻撃
、SYNキャッシュ技術
、SYNクッキー技術
、SYNプロキシファイアウォール
などの詳細については、“三回のハンドシェイク、四回のフィニッシュ” を本当に理解していますか?を参照してください。
TCP の信頼性のある伝送#
信頼性のある伝送は次の条件を満たす必要があります:
-
伝送チャネルでエラーが発生しないこと;
-
伝送データの正確性を保証し、エラーがなく、損失がなく、重複せず、順序通りに到達すること。
TCP の信頼性のある伝送の実現:
-
三回のハンドシェイクを使用して TCP 接続を確立し、四回のフィニッシュを使用して TCP 接続を解放することで、確立された伝送チャネルが信頼できることを保証します。
-
TCP はデータ伝送の正確性を保証するために
ARQプロトコル
を採用しています。 -
TCP は
スライディングウィンドウプロトコル
を使用して、受信側が受信したデータを適時処理し、フロー制御を行います。 -
TCP は
スロースタート
、輻輳回避
、早期再送
、早期回復
を使用して輻輳制御
を行い、ネットワークの輻輳を避けます。
スライディングウィンドウプロトコル#
スライディングウィンドウプロトコルは、データ送信者が送信ウィンドウを持ち、送信ウィンドウ内のデータが送信を許可され、受信側からの確認メッセージや受信ウィンドウのサイズ通知に応じて、送信ウィンドウの開始位置とサイズを動的に調整します。
ウィンドウのスライドには 3 つの状況があります:
- 前端が右に移動する。この状況は、データが送信され、確認されたときに発生します。
- 後端が右に移動し、より多くのデータを送信できるようにします。この状況は、受信ウィンドウが増加したり、ネットワークの輻輳が緩和されたときに発生します。
- 後端が左に移動する。この状況は、受信側が送信ウィンドウを縮小したい場合に発生し、TCP 標準ではこの状況の発生を強く推奨しません。なぜなら、送信者がウィンドウの縮小通知を受け取ったときに、すでに縮小部分のデータを送信している可能性があり、エラーを引き起こす可能性があるからです。
- ウィンドウの前端は左に移動できません。なぜなら、TCP はウィンドウ外で確認されたデータをキャッシュから削除します。
ARQ プロトコル#
ARQ 自動再送要求(Automatic Repeat-reQuest)は、データ伝送中に確認
(Acknoledgements、つまり一般的に言われるACK
、受信側がメッセージを送信し、送信側にパッケージを正しく受信したかどうかを知らせる)とタイムアウト
(Timeouts、確認メッセージを受信する前に待機する一定の時間)メカニズムを使用して、不安定なネットワーク上で信頼性のあるデータ伝送を実現するエラー制御方法戦略です。これにはストップアンドウェイトARQプロトコル
と連続ARQプロトコル
、エラー検出(Error Detection)
、正の確認(Positive Acknowledgment)
、タイムアウト後の再送(Retransmission after Timeout)
および負の確認と再送(Negative Acknowledgment and Retransmission)
などのメカニズムが含まれます。
ストップアンドウェイト ARQ:
「ストップアンドウェイト」とは、各パケットを送信した後に送信を停止し、相手の確認を待ち、相手の確認を受け取った後に次のパケットを送信することを指します。2 つのエラー状況があります。
- 受信側がエラーデータパケットを受信した場合、パケットを直接破棄します。
- 送信者が一定時間内に確認を受信しない場合、パケットを再送信します。つまり、タイムアウト再送です。
連続 ARQ プロトコル:
-
スライディングウィンドウプロトコルと自動再送要求技術が組み合わさって連続 ARQ プロトコルが形成されます。連続 ARQ プロトコルは、タイムアウト再送データ方式に応じて
後退NフレームARQプロトコル
と選択的再送ARQプロトコル
に分かれます。 -
送信者が確認を受け取るたびに、送信ウィンドウを 1 つのパケットの位置だけ前にスライドさせます。
-
受信側は一般的に
累積確認(ACKメカニズム)
の方式を採用します。つまり、受信側は受信したパケットに対して逐次確認を送信する必要はなく、いくつかのパケットを受信した後、順番に到達した最後のパケットに対して確認を送信することができます。これにより、このパケットまでのすべてのパケットが正しく受信されたことを示します。
後退NフレームARQ(Go-Back-N ARQ)
#
GBN は、データフレームを送信した後、確認フレームを待たずに連続していくつかのフレームを送信し、送信しながら確認フレームを待つことができます。確認フレームを受信した場合、データフレームを引き続き送信できます。待機時間が短縮され、利用率が向上します。ただし、エラーフレームを受信した場合、すべてのそのフレーム以降のフレームを再送信する必要があります。
選択的再送/拒否ARQ(Selective Repeat/Reject ARQ)
#
後退 N フレーム ARQ に対して、エラーフレームを受信した場合、すべてを再送信する必要はなく、エラーのあるフレームだけを選択して再送信する必要があります。これにより、再利用率がさらに向上しますが、同時にスペースを犠牲にします。なぜなら、すでに受信した正しい情報をキャッシュしておく必要があるからです。すべての情報が正しく受信されるまで確認を送信しません。
フロー制御#
TCP 接続を介してデータを送信する場合、送信者がデータを送信する速度が遅いとリソースが無駄になります。送信者がデータを送信する速度が速すぎると、受信者が受信しきれず、データが失われる可能性があります。フロー制御は、受信者が受信できる範囲内で合理的かつ迅速にデータを送信することを指します。
スライディングウィンドウに基づくフロー制御#
TCP 接続が確立されると、受信側は確認メッセージ内で自分の受信ウィンドウのサイズを示します。各確認メッセージを送信するたびに、状況に応じて受信ウィンドウのサイズを動的に調整し、送信者に通知します。以下の図を参照してください:
送信者は、シーケンス番号 1 から始まる 100 バイトのデータを送信し、受信者は確認メッセージ内で自分の受信ウィンドウのサイズを 300 バイトと宣言します。その後、送信者は 300 バイトのデータを送信し、受信者は確認メッセージ内で自分の受信ウィンドウのサイズを 50 バイトに調整します。送信者は 50 バイトのデータを送信した後、受信者からの確認メッセージを受け取り、そのメッセージ内で受信ウィンドウが 0 であることを示します。
受信者の受信ウィンドウが 0 の場合、送信者はデータを送信しなくなります。受信者が受信ウィンドウのサイズが変更されたことを示す確認メッセージを送信するまで、データを送信しません。ただし、この確認メッセージが送信者に届かない場合、双方は待機状態になり、デッドロックが発生します。このような状況を防ぐために、TCP は相手の受信ウィンドウが 0 であるとき、定期的に探査メッセージを送信するための持続タイマーを起動します。相手の受信ウィンドウが 0 の状態が変更されたかどうかを確認します。
さらに、TCP 標準では、受信者の受信ウィンドウが 0 のとき、通常のデータを受信しなくなりますが、ゼロウィンドウ探査メッセージ、確認メッセージ、緊急データを含むメッセージを受信することができます。
輻輳制御#
TCP の輻輳制御に一般的に使用されるアルゴリズムには、スロースタート
、輻輳回避
、早期再送
、早期回復
の 4 つがあります。
スロースタート#
TCP は送信者に輻輳ウィンドウを維持し、cwnd と呼ばれ、輻輳ウィンドウの値は SMSS に関連しています。SMSS は送信の最大セグメント長です。
スロースタートアルゴリズムでは、輻輳ウィンドウが初期化された後、新しいパケットの確認を受け取るたびに、輻輳ウィンドウが 1 つの SMSS のサイズだけ増加します。輻輳ウィンドウはバイト単位ですが、スロースタートは SMSS のサイズ単位で増加します。スロースタートアルゴリズムに従うと、1 回の伝送後に輻輳ウィンドウは 2 倍に増加します。これは指数的な増加関係です。
輻輳回避#
スロースタートアルゴリズムは、輻輳ウィンドウ cwnd 変数を維持するだけでなく、もう 1 つの変数スロースタート閾値 ssthresh を維持します。cwnd が指数的に増加して ssthresh 以上になると、スロースタートアルゴリズムを使用せず、輻輳回避アルゴリズムを使用して輻輳制御を行います。
輻輳回避アルゴリズムでは、確認を受け取るたびに cwnd を 1/cwnd 個の SMSS だけ増加させます。つまり、スロースタートアルゴリズムのように 1 回の伝送で cwnd が倍増するのではなく、1 回の伝送で 1 つの SMSS が増加します。これは加算的な増加関係であり、輻輳が発生した場合(タイムアウトまたは重複確認を受信した場合)、cwnd は 1 つの SMSS に設定されます。ssthresh は現在のウィンドウサイズの半分に設定されますが、最小で 2 つのパケットセグメントです。
要約すると、加算的増加、乗算的減少です。
早期再送#
個々のパケットがネットワークで失われた場合、ネットワークが輻輳していない場合、送信者は確認メッセージを受信できず、タイムアウト後にそのパケットを再送信します。送信者はネットワークが輻輳していると誤解し、誤ってスロースタートアルゴリズムを起動し、伝送効率が低下します。
早期再送アルゴリズムを使用すると、送信者は個々のパケットの損失を早期に知ることができます。早期再送アルゴリズムでは、受信側が確認を遅延させず、順序が逆のパケットを受信しても、受信したパケットの確認を即座に送信する必要があります。以下の図を参照してください:
受信側は M1 を受信した後、M1 の確認メッセージを送信し、M2 パケットが失われ、受信側は M3、M4、M5 を受信するたびに M1 パケットの確認を繰り返し送信します。早期再送アルゴリズムでは、3 回の重複確認を受信した後、送信者は M2 パケットが失われたと見なし、タイムアウトを待たずに M2 パケットを即座に再送信します。これにより、送信者がネットワークが輻輳していると誤解するのを防ぎます。
早期回復#
早期再送アルゴリズムが実行された後、送信者は単に個々のパケットが失われたことを知っており、ネットワークが輻輳しているわけではありません。その後、スロースタートアルゴリズムを実行するのではなく、早期回復アルゴリズムを実行します:閾値 ssthresh を cwnd/2 に調整し、同時に cwnd を ssthresh + 3 SMSS に設定します。送信者は、3 つの確認パケットを受信したため、3 つのパケットがネットワークを離れ、受信者のキャッシュに到達したと見なします。これらの 3 つの確認パケットはもはやネットワークリソースを占有せず、輻輳ウィンドウのサイズを増加させることができます。
輻輳制御とフロー制御の違い#
-
輻輳制御:輻輳制御はネットワークに作用し、過剰なデータがネットワークに注入されるのを防ぎ、ネットワークの負荷が過大になるのを避けます。
-
フロー制御:フロー制御は受信者に作用し、送信者の送信速度を制御して受信者が受信できるようにし、パケットの損失を防ぎます。
五、TCP と UDP の違い#
- TCP はバイトストリーム指向で、UDP はメッセージ指向です。
- TCP は接続指向(3 回のハンドシェイクが必要)で、UDP は非接続指向です。
- TCP は信頼性のあるデータ伝送サービスを提供し、パケットの損失再送機能があり、データの順序を保証しますが、UDP はパケットの損失が発生する可能性があり、データの順序を保証しません。
- 各 TCP 接続は点対点であり、UDP は一対一、一対多、多対一、多対多の相互通信をサポートします。
- TCP はシステムリソースを多く要求し、UDP は少なくて済みます。
具体的なプログラミング時の違い、socket () のパラメータが異なります。
- UDP サーバーは listen と accept を呼び出す必要がありません。
- UDP のデータ送受信には sendto/recvfrom 関数を使用します。
- TCP:アドレス情報は connect/accept 時に確定します。
- UDP:sendto/recvfrom 関数で毎回アドレス情報を指定する必要があります。
- UDP:shutdown 関数は無効です。
六、HTTP プロトコル#
HTTP プロトコルは、ハイパーテキスト転送プロトコルの略で、英語では Hyper Text Transfer Protocol です。これは、WEB サーバーからローカルブラウザにハイパーテキストマークアップ言語(HTML)を転送するためのプロトコルで、TCP/IP 通信プロトコルに基づいてデータを伝送します。
メッセージ形式#
一般的なリクエストヘッダー#
Accept
:サーバーがサポートするデータタイプをクライアントに通知します。Accept-Charset
:サーバーにクライアントが使用するエンコーディング形式を通知します。Accept-Encoding
:サーバーにクライアントがサポートするデータ圧縮形式を通知します。Accept-Language
:クライアントの言語環境。Host
:クライアントがこのヘッダーを使用してサーバーにアクセスしたいホスト名。If-Modified-Since
:クライアントがこのヘッダーを使用してサーバーにリソースのキャッシュ時間を通知します。Referer
:クライアントがこのヘッダーを使用してサーバーに、どのリソースからサーバーにアクセスしたかを通知します(盗用防止)。User-Agent
:クライアントがこのヘッダーを使用してサーバーに、クライアントのソフトウェア環境を通知します。Cookie
:クライアントがこのヘッダーを使用してサーバーにデータを送信できます。Connection
:このリクエストが処理された後、接続を切断するか、接続を維持するかを示します。Date
:現在の時間値。
一般的なレスポンスヘッダー#
Location
: リダイレクト先のアドレスを示し、このヘッダーは 302 のステータスコードと一緒に使用されます。Server
: サーバーのタイプを示します。Content-Encoding
: サーバーがブラウザに送信するデータの圧縮タイプを示します。Content-Length
: サーバーがブラウザに送信するデータの長さを示します。Content-Language
: サーバーがサポートする言語を示します。Content-Type
: サーバーがブラウザに送信するデータのタイプと内容のエンコーディングを示します。Last-Modified
: サーバーリソースの最終変更時間を示します。Refresh
: 定期的に更新することを示します。Content-Disposition
: ブラウザにリソースをダウンロード方式で開くように指示します(ファイルダウンロード時に使用されます)。Transfer-Encoding
: ブラウザにデータの転送形式を通知します。Set-Cookie
: サーバーがブラウザに送信するクッキー情報を示します(セッション管理に使用されます)。Expires
: ブラウザに返送されたリソースをキャッシュする期間を通知します。-1 または 0 はキャッシュしないことを示します。Cache-Control
: no-cache。Pragma
: no-cache。
サーバーは上記の 2 つのヘッダーを使用して、ブラウザにデータをキャッシュしないように制御します。Connection
: サーバーとブラウザの接続状態を示します。close:接続を切断、keep-alive:接続を維持します。
リクエストステータスコード#
ステータスコードの分類#
- 1XX- 情報型、サーバーがリクエストを受信し、リクエスト者が操作を続ける必要があることを示します。
- 2XX- 成功型、リクエストが正常に受信され、理解され、処理されたことを示します。
- 3XX - リダイレクト、リクエストを完了するためにさらなる操作が必要です。
- 4XX - クライアントエラー、リクエストに構文エラーが含まれているか、リクエストを完了できません。
- 5XX - サーバーエラー、サーバーがリクエストを処理する過程でエラーが発生しました。
一般的なリクエストステータスコード#
200
OK リクエストが成功しました。204
No Content 内容なし、サーバーがリクエストを正常に処理しましたが、何も返しませんでした。301
Moved Permanently リクエストされたリソースが移動しました。永久リダイレクト。302
Found 見つかりました。臨時リダイレクト。304
Not Modified 未変更、クライアントのキャッシュリソースが最新であるため、クライアントはキャッシュを使用する必要があります。400
Bad Request クライアントのリクエストに構文エラーがあり、サーバーが理解できません。401
Unauthorized 未承認、クライアントがデータにアクセスする権限がありません。403
Forbidden 禁止、アクセス権がありません。404
Not Found リクエストされたリソースが存在しません。誤った URL が入力された可能性があります。405
Method Not Allowed メソッドが許可されていません。406
Not Acceptable リクエストされたリソースの内容特性がリクエストヘッダーの条件を満たさないため、応答エンティティを生成できません。500
Internal Server Error 内部サーバーエラー。502
Bad Gateway 無効なゲートウェイ、ゲートウェイまたはプロキシとしてのサーバーがリクエストを実行する際に無効な応答を受信しました。503
Service Unavailable サービスが利用できません。サーバーがメンテナンス中または過負荷のため応答できませんでした。504
Gateway Timeout ゲートウェイ接続タイムアウト、ゲートウェイまたはプロキシのサーバーが指定された時間内に応答できませんでした。
Post と Get リクエストの違い#
-
GET リクエストのデータは URL の後に付加されます(つまり、データを HTTP プロトコルヘッダーに置くことを意味します)。URL と送信データは?で分割され、パラメータは & で接続されます。POST は送信データを HTTP パッケージのボディに置きます。
-
GET で送信できるデータ量は比較的小さい(データが URL の後に付加されるため)、POST は送信できるデータ量が大きく、ブラウザとサーバーには異なる制限があります。
-
POST の安全性は GET より高く、GET のデータは URL に含まれているため、誰でも見ることができます。GET が安全であると言われるのは、単に情報を変更しないことを指します。GET はリソース情報を取得 / 照会するために使用され、POST はリソース情報を更新するために使用されます。
-
GET は冪等であり、POST は冪等ではありません。
-
GET のエンコーディングタイプは application/x-www-form-url であり、POST のエンコーディングタイプは encodedapplication/x-www-form-urlencoded または multipart/form-data です。
-
GET の履歴パラメータはブラウザの履歴に保存されます。POST のパラメータはブラウザの履歴に保存されません。
冪等性#
HTTP メソッドの冪等性は、一度のリクエストと複数回のリクエストが同じ副作用を持つべきであることを指します。つまり、同じリクエストを 1 回送信することと N 回送信することの効果は同じです!
冪等なメソッド:GET、DELETE、PUT
PUT と POST はどちらも作成または更新を行いますが、唯一の違いは POST が冪等でないことです。
http1.x/2.0#
http1.1#
-
永続接続(persistent connection)が導入され、TCP 接続はデフォルトで閉じず、複数のリクエストで再利用できます。Connection: keep-alive を宣言する必要はありません。
-
パイプライン機能(pipelining)が導入され、同じ TCP 接続でクライアントは同時に複数のリクエストを送信でき、HTTP プロトコルの効率がさらに向上します。
-
新しいメソッド:PUT、PATCH、OPTIONS、DELETE が追加されました。
-
HTTP プロトコルはステートレスであり、各リクエストにはすべての情報を添付する必要があります。リクエストの多くのフィールドは重複しており、帯域幅を無駄にし、速度に影響を与えます。
http2.0#
-
http/2 は完全なバイナリプロトコルであり、ヘッダー情報とデータ本体はすべてバイナリであり、総称して「フレーム」(frame)と呼ばれます:ヘッダー情報フレームとデータフレーム。HTTP1.x でデータを明文で転送することによって引き起こされるセキュリティ問題を回避します。
-
TCP 接続の再利用が可能で、1 つの接続でクライアントとブラウザが同時に複数のリクエストや応答を送信でき、順序に従う必要がなく、ヘッダーブロッキングの問題を回避します。この双方向のリアルタイム通信をマルチプレクシング(Multiplexing)と呼びます。
-
HTTP/2 は、サーバーがリクエストなしにクライアントにリソースをプッシュすることを許可します。つまり、サーバープッシュです。
-
** ヘッダー情報圧縮メカニズム(header compression)** が導入され、ヘッダー情報は gzip または compress で圧縮されてから送信されます。
https#
HTTPS は HTTP を介して通信し、SSL/TLS プロトコルを使用してデータパケットを暗号化します。これは HTTP の安全版であり、主な違いは次のとおりです:
- HTTPS プロトコルは CA に証明書を申請する必要があります。
- HTTP と HTTPS は異なるポートを使用し、前者は 80、後者は 443 です。
- HTTP プロトコルは TCP の上で動作し、すべての伝送内容は明文であり、HTTPS は SSL/TLS の上で動作し、SSL/TLS は TCP の上で動作し、すべての伝送内容は暗号化されます。
- HTTPS は運営者のハイジャックを効果的に防止できます。
七、ブラウザがドメイン名を入力してページを表示するプロセス#
イベントの順序:
- DNS ドメイン名解決:ブラウザキャッシュ --> オペレーティングシステムキャッシュ --> ローカル host ファイル --> ルーターキャッシュ --> ISP DNS キャッシュ --> トップレベル DNS サーバー / ルート DNS サーバーがドメイン名に対応する IP アドレスを検索します。
- TCP 接続の確立:TCP は三回のハンドシェイクを使用してサーバーと接続を確立し、信頼性のある伝送サービスを提供します。
- HTTP リクエストの送信:TCP 接続を介して HTTP メッセージをサーバーに送信します。
- サーバーがリクエストを処理し、HTTP メッセージを返します。
- ブラウザがページをレンダリングします:まず、ブラウザが HTML ファイルを解析して DOM ツリーを構築し、次に CSS ファイルを解析してレンダーツリーを構築します。レンダーツリーが構築されると、ブラウザはレンダーツリーのレイアウトを開始し、画面に描画します。
関連するプロトコル:
-
アプリケーション層:HTTP(WWW アクセスプロトコル)、DNS(ドメイン名解決サービス)
DNS はドメイン名(domain name)と IP アドレス(IP address)の対照表を維持し、メッセージのドメイン名を解決します。 -
トランスポート層:TCP(HTTP に信頼性のあるデータ伝送を提供)、UDP(DNS は UDP を使用して伝送します)。
-
ネットワーク層:IP(IP データパケットの伝送とルーティング)、ICMP(ネットワーク伝送プロセス中のエラー検出を提供)、ARP(ローカルのデフォルトゲートウェイ IP アドレスを物理 MAC アドレスにマッピングします)。
八、セッションとクッキーの違い#
-
クッキーのデータはクライアントのブラウザに保存され、セッションデータはサーバーに保存されます。
-
クッキーはあまり安全ではなく、他の人がローカルに保存されたクッキーを分析し、クッキーを偽造することができます。
-
セキュリティを考慮すると、セッションを使用するべきです。
-
セッションは一定の時間内にサーバーに保存されます。アクセスが増えると、サーバーのパフォーマンスを比較的占有します。サーバーのパフォーマンスを軽減するために、クッキーを使用するべきです。
-
単一のクッキーが保存できるデータは 4K を超えることはできず、多くのブラウザは 1 つのサイトで最大 20 個のクッキーを保存することを制限しています。
補足#
セッションはある程度クッキーに依存しています。サーバーがセッションメカニズムを実行すると、セッションの ID 値が生成され、この ID 値がクライアントに送信されます。クライアントは毎回リクエストを行う際にこの ID 値を HTTP リクエストのヘッダーに送信し、この ID 値はクライアントに保存され、保存されるコンテナはクッキーです。
九、長接続と短接続および WebSocket#
長接続と短接続#
長接続と短接続の違い#
HTTP/1.0 では、デフォルトで短接続が使用されます。つまり、ブラウザとサーバーが HTTP 操作を行うたびに接続を確立し、タスクが終了すると接続が切断されます。
HTTP/1.1 以降、デフォルトで長接続が使用され、接続特性を保持します。長接続を使用する HTTP プロトコルは、応答ヘッダーにConnection:keep-alive
を設定します。
長接続を使用する場合、ウェブページが開かれた後、クライアントとサーバー間の HTTP データを転送するための TCP 接続は閉じず、クライアントが再度このサーバー上のウェブページにアクセスする場合、すでに確立された接続を使用します。Keep-Alive は永久に接続を保持するわけではなく、保持時間があり、異なるサーバーソフトウェア(Apache など)でこの時間を設定できます。長接続を実現するには、クライアントとサーバーの両方が長接続をサポートする必要があります。
HTTP プロトコルの長接続と短接続は、本質的には TCP プロトコルの長接続と短接続です。
長接続と短接続の適用シーン#
-
長接続は、頻繁に操作が行われ、点対点の通信が必要で、接続数が多くない場合に多く使用されます。各 TCP 接続は 3 回のハンドシェイクを必要とし、時間がかかります。各操作が接続を確立し、操作を行う場合、処理速度が大幅に低下します。したがって、各操作が完了した後、接続を切断せず、次の処理時にデータパケットを直接送信することができます。例えば、データベースの接続は長接続を使用します。短接続を頻繁に使用すると、ソケットエラーが発生し、頻繁なソケットの作成もリソースの無駄になります。
-
一方、WEB サイトの HTTP サービスは一般的に短接続を使用します。長接続はサーバーに一定のリソースを消費するため、WEB サイトのように頻繁に数千、数万、さらには数億のクライアントの接続を使用する場合、短接続の方がリソースを節約できます。長接続を使用し、同時に数千のユーザーがいる場合、各ユーザーが接続を占有すると、想像に難くありません。したがって、同時接続数が多く、各ユーザーが頻繁に操作する必要がない場合は短接続が適しています。
短ポーリングと長ポーリング#
短接続と長接続とは本質的に異なります。長接続と短接続はクライアントとサーバー間の TCP 接続を確立し、保持するメカニズムです。一方、長ポーリングと短ポーリングは、クライアントがサーバーにリクエストを送り、サーバーが応答を返す方法を指します。
-
短ポーリング:HTTP リクエストを繰り返し送信し、ターゲットイベントが完了したかどうかを確認します。利点:簡単に記述でき、欠点:帯域幅とサーバーリソースを無駄にします。
-
長ポーリング:サーバーが HTTP リクエストを保持します(死ループまたはスリープなどの方法を使用して)、ターゲット時間が発生するまで(データが到着するのを待つか、適切なタイムアウトを待つ)、HTTP 応答を返します。利点:メッセージがない場合、頻繁にリクエストを送信しませんが、欠点:記述が複雑です。
WebSocket#
WebSocket 接続の確立#
クライアントブラウザは、サーバーに HTTP リクエストを最初に送信します。このリクエストは通常の HTTP リクエストとは異なり、いくつかの追加ヘッダー情報が含まれています。その中の追加ヘッダー「Upgrade: WebSocket
」は、プロトコルのアップグレードを要求する HTTP リクエストであることを示します。
WebSocket と HTTP 長接続の違い#
- HTTP1.1 は Connectionを使用して長接続を実現し、HTTP 1.1 はデフォルトで持続接続を行います。1 つの TCP 接続で複数の HTTP リクエストを完了できますが、各リクエストには依然として個別にヘッダーを送信する必要があります。Keep-Alive は永久に接続を保持するわけではなく、保持時間があり、異なるサーバーソフトウェア(Apache など)でこの時間を設定できます。
- WebSocket の長接続は、真の全二重であり、最初の TCP リンクが確立された後、後続のデータは双方が送信でき、リクエストヘッダーを送信する必要がなく、この接続はクライアントまたはサーバーのいずれかが接続を閉じるまで持続します。HTTP 長接続とは異なり、WebSocket は接続を閉じるタイミングをより柔軟に制御できます。HTTP プロトコルの Keep-Alive が到達すると、サーバーはすぐに接続を閉じます(これは非常に非人道的です)。