コンピュータネットワークのまとめ#
一、アーキテクチャ#
アプリケーション層
:アプリケーション層プロトコルは、アプリケーションプロセス間の通信と相互作用のルールを定義し、特定のアプリケーションにデータ転送サービスを提供します。例えば、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 つの部分に分割することです。
サブネットマスクの計算#
サブネット数を使用してサブネットマスクを計算#
計算ルール:
-
サブネット数を 2 進数に変換して表現します。
-
その 2 進数のビット数を取得し、N とします。
-
その IP アドレスのクラスサブネットマスクを取得し、ホストアドレス部分の前 N ビットを 1 に設定することで、その IP アドレスのサブネットマスクを得ます。
B クラス IP アドレス 168.195.0.0 を 27 個のサブネットに分割する場合:
-
27=11011
-
この 2 進数は 5 ビットで、N = 5
-
B クラスアドレスのサブネットマスク 255.255.0.0 のホストアドレスの前 5 ビットを 1 に設定し、255.255.248.0 が 27 個のサブネットに分割された B クラス IP アドレス 168.195.0.0 のサブネットマスクとなります。
ホスト数を使用してサブネットマスクを計算#
計算ルール:
-
ホスト数を 2 進数に変換して表現します。
-
ホスト数が 254 以下の場合(予約された 2 つの IP アドレスを除外することに注意)、そのホストの 2 進数のビット数を取得し、N とします。ここで N<8 であることが確実です。254 を超える場合、N>8 となり、ホストアドレスは 8 ビット以上を占有します。
-
255.255.255.255 を使用して、そのクラスの IP アドレスのホストアドレスビットをすべて 1 に設定し、後ろから前に向かって N ビットをすべて 0 に設定することで、サブネットマスクの値を得ます。
B クラス IP アドレス 168.195.0.0 をいくつかのサブネットに分割し、各サブネット内に 700 台のホストがある場合:
-
700=1010111100
-
この 2 進数は 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 flood攻撃
、Syn Cache技術
、Syn Cookie技術
、SYN Proxyファイアウォール
などの詳細については、“三回のハンドシェイク、四回のフィニッシュ” を本当に理解していますか?を参照してください。
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:
「停止待機」とは、1 つのパケットを送信した後、確認を待つために送信を停止し、相手の確認を受け取った後に次のパケットを送信することを指します。これには 2 つのエラー状況があります。
- 受信側がエラーデータパケットを受信した場合、パケットを直接破棄します。
- 送信側が一定時間内に確認を受信しない場合、パケットを再送信します。つまり、タイムアウト後の再送です。
連続 ARQ プロトコル:
-
スライディングウィンドウプロトコルと自動再送要求技術が組み合わさって連続 ARQ プロトコルが形成されます。連続 ARQ プロトコルは、タイムアウト再送データ方式に応じて
後退NフレームARQプロトコル
と選択的再送ARQプロトコル
に分かれます。 -
送信側は確認を受け取るたびに、送信ウィンドウを 1 つのパケットの位置に前進させます。
-
受信側は一般的に
累積確認(ACKメカニズム)
の方式を採用します。つまり、受信側は受信したパケットを 1 つずつ確認する必要はなく、いくつかのパケットを受信した後、順番に到着した最後のパケットに対して確認を送信できます。これにより、このパケットまでのすべてのパケットが正しく受信されたことを示します。
後退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 回の伝送後に輻輳ウィンドウが倍増します。これは指数的な増加関係です。
輻輳回避#
スロースタートアルゴリズムは、輻輳ウィンドウ 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
:サーバーがブラウザに送信する cookie 情報を示します(セッション管理に使用)。Expires
:ブラウザに送信されたリソースをどれくらいの時間キャッシュするかを伝えます。-1 または 0 はキャッシュしないことを示します。Cache-Control
: no-cachePragma
: 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 回と複数回リクエストを送信した場合、同じ副作用を持つべきであることを指します。つまり、同じリクエストを 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 は、サーバーがリクエストなしにクライアントにリソースをプッシュすることを許可します。これをサーバープッシュと呼びます。
-
ヘッダー情報圧縮メカニズムを導入しました。ヘッダー情報は 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 接続には三回のハンドシェイクが必要で、これには時間がかかります。各操作が接続を確立してから行われる場合、処理速度が大幅に低下します。そのため、各操作が完了した後、接続を切断せず、次の処理時に直接データパケットを送信することができます。例えば、データベースの接続には長接続を使用します。短接続を頻繁に使用すると、ソケットエラーが発生し、頻繁なソケットの作成もリソースの無駄遣いになります。
-
一方、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 が時間が来ると、サーバーがすぐに接続を閉じるのとは異なります(これは非常に非人道的です)。