🦔

インターネット通信の流れ

2020/09/24に公開1

はじめに

皆さんのパソコンやスマホから送られた「このページを見たいです」「このファイルをダウンロードしたいです」といった要求(=リクエスト)は、インターネットの中で、TCP/IPというプロトコル(=ルール)に従って通信されています。

では、このTCP/IPとはどのようなルールで、具体的にはどのように通信が行われているのでしょうか?
一通りの流れを、ざっくりと追っていきたいと思います。

※分かり易さ優先で書きます。そして詳細は端折ります!  
あくまでイメージを掴むために本記事を利用して頂き、細かいところは各自学習して頂ければ幸いです。

OSI参照モデルとTCP/IP

OSI参照モデル

OSI参照モデルとは、ネットワーク通信を行う際に必要な役割を7つに分類した、云わばネットワーク通信の「型」のようなものです。
全ての端末で共通する通信の型を定義し、それに沿った通信が行われることで、端末仕様が異なっていても問題なく通信が成立するよう、ISOという団体によって提唱されました。
ISOが定義したOSI参照モデル... ややこしいですね。。

ここで注意したいのは、OSI参照モデルが、あくまでモデルだと言うことです。
つまり、通信を行う機器が必ずこの通りに実装する必要は無いのです。

TCP/IP

TCP/IPとは、米国国防高等研究計画局(DARPA)によって1974年に定義された、インターネットなどのコンピューターネットワークにおける、プロトコル群の総称です。
つまり、インターネットを用いて通信を行う際の様々なルールを、まとめて「TCP/IP」と呼んでいるのです。

そしてこのTCP/IPは、通信の階層を次の4つに分類し、それぞれに役割を与えています。

「対応するOSI参照モデル階層」とあるように、構造こそ違えど、通信における基本的な役割はOSI参照モデルに対応する形となっています。
この両者の詳しい違いに関しては、こちらの記事を参照下さい。

では、このTCP/IPにおいて、データはどのような流れを経て各階層を通過し、通信が行われているのでしょうか? 流れを追っていきましょう。

TCP/IPにおける通信の流れ

基本的にTCP/IPにおける通信は、ざっくりと

  1. 運搬に必要な情報をデータに付与し
  2. そのデータを目的地まで運び
  3. 到着したら、付与された情報を紐解きつつ、データを指定アプリケーションまで届ける
    という流れで行われます。

そして、
1を行うために、アプリケーション層からネットワークインターフェース層へと順にデータを下降させつつ、それぞれの層でヘッダと呼ばれる情報を付与し、
2を行うために、ネットワーク層でルーターと呼ばれる機器を用いながらデータの転送を行い、
3を行うために、ネットワークインターフェース層からアプリケーション層へとデータを上昇させつつ、各ヘッダの情報を読み解き、指定のアプリケーションにデータを送り届ける
ということを行っています。

1のデータ下降から、中継、3のデータ上昇に至るまで、各層の働きと特徴をざっと見ていきましょう。

1.運搬に必要な情報をデータに付与

アプリケーション層

皆さんが普段使用しているサービスは、このアプリケーション層に属しています。
そして、これらのサービスは皆「何を実現したいのか」によって、それぞれ異なるルール(=プロトコル)に従い開発がなされています。

例えば、webサービスでデータのやり取りを行いたいのであれば、HTTPプロトコルに、
メールを贈りたいのであれば、SMTPプロトコルに
ファイルを転送したいのであれば、FTPプロトコルに従うということが定められているのです。

通信は、これらのアプリケーション内のアクションを通じて、データを送信する必要性が生じることで発生し、発生したデータは、下層のトランスポート層へと運ばれます。
(Ex:リンクボタンのクリック、メールの送信など)

また、ここで発生したデータがどのような通信方式によって運ばれていくのかは、アプリケーションが従うプロトコルによって決まられています。
アプリケーション層では、ひとつ下のトランスポート層にデータを渡す際、この通信方式に関しても指示を行っているのです。
(※具体的には、下層で行う通信が、TCP通信なのか、それともUDP通信なのかの指示を行います。)

このアプリケーション層で発生したデータをメッセージと呼ぶので、合わせて覚えておきましょう。

トランスポート層

トランスポート層は、データを該当アプリケーションまで届けることに責務を負っています。
つまり、「どのアプリケーションなのか」を示すポート番号の扱いが、この層の主な仕事となってくるのです。

この層では、TCPUDPと呼ばれる2つのプロトコルが存在します。
どちらも上記のように通信を行うプログラムの間でのデータ伝送を行うことに変わりは無いのですが、主な特徴として、
TCP:正確性重視でデータを送信
(データが正常に届くことを保証する仕組みが存在。正確だけどその分遅い。)
UDP:速度重視でデータを送信
(データを垂れ流す形式。早いけど正確じゃない。)
といった違いが存在しています。

この2つのうち、どちらの通信方式を取るのかは、アプリケーション層からの指示によって決まります。
正確には、アプリケーション層がHTTPプロトコルであればTCPを、DNSであればUDPを...といった具合に使用プロトコルによって決められており、それぞれ、決まった手順を踏んで通信を行っていくのです。

また、このトランスポート層では、アプリケーション層から受け取ったデータに対して、
・ 宛先のポート番号は何番か
・ 送信元のポート番号は何番か
などの情報が格納されたヘッダと呼ばれるものを付け足します。
文頭に出た通信対象のアプリケーションポート番号を、ヘッダという形でデータに付与しているのですね。

このように、元々のデータ+ヘッダ という新たなデータが作成され、それが下層のネットワーク層へと送られます。

ヘッダの呼称として、
TCP形式の通信時に付与されるヘッダを、TCPヘッダ
UDP形式の通信時に付与されるヘッダをUDPヘッダと呼んでいるので、ここも合わせて覚えておきましょう。

更に、トランスポート層では、元々のデータを運びやすい適切なサイズに分割します。
この、トランスポート層内で分割されたデータの破片のことをセグメントと呼び、各セグメントには、それぞれにヘッダが付与されることとなります。

つまり、メッセージ + (TCPヘッダ or UDPヘッダ) = セグメント
という図式が成り立つのです。

ネットワーク層

ネットワーク内でデータを転送することがこの層の責務となります。
そして、ネットワーク内における宛先には、IPアドレスが使用されています。

つまり、
・宛先のIPアドレス
・送信元のIPアドレス
などの情報が必要となってくるのです。

よって、ネットワーク層では、これらの情報や上位層のプロトコルタイプ(TCPなのかUDPなのか)などをIPヘッダとしてデータに付与しているのです。

また、インターネット層で付与されるヘッダーをIPヘッダと呼び、トランスポート層から渡されたセグメントにIPヘッダを付け足したものを、パケットと呼びます。

IPヘッダ + セグメント = パケット
といった図式になるので、覚えておきましょう。

ネットワークインターフェイス層

この層では直接的に接続されたネットワーク内でのデータ転送が行われており、その転送方法としてイーサネットと呼ばれるプロトコルが広く普及しています。

このイーサネットにつながれた各端末をホストと呼び、各ホスト固有のIDのようなものをMACアドレスと呼びます。
そして、このイーサネットでは、MACアドレスを使用してデータの転送を行っています。
つまり、逆の見方をすると、イーサネット内でのデータの転送には、MACアドレスが必須なのです。

よって、転送用のデータにには、
・位置階層上のプロトコルを示したイーサネットタイプ(TCP/IPの場合はIPプロトコル)
・送信元MACアドレス
・宛先MACアドレス
などが必要になってきます。これらをまとめて、イーサネットヘッダとして、パケットに付与します。

また、パケットにイーサネットヘッダを付け足したこのデータを、フレームと呼びます。
イーサネットヘッダ + パケット = フレームという図式ですね。

そしてもう一つこの層の重要な役割として、コンピューター内のデータ(0と1からなるデータ)と電気信号を変換するということが挙げられます。
データ送信をする際、イーサネットヘッダが付与されたフレームは、まだコンピューター用のデータです。
これを実際の通信機器に流す前に、電気信号に変換する必要があるのです。

これはOSI参照モデルで言う物理層の役割となるのですが、TCP/IPではデータリンク層と物理層をまとめて1つの層としてしまっているので、ここでまとめてしまいましょう。

フレームが完成し、それを電気信号に変換したら、いよいよ2番、データを目的地まで運ぶ処理を行っていきます。

2.データを目的地まで運ぶ

データを目的地まで運ぶのは、ネットワーク層の役割です。
そして、データを運ぶために、ルーターと呼ばれる機器が使用されます。

インターネットは、各ネットワークがルーターを介して繋がっている構図となっています。

ですので、データが最終目的地であるアプリケーションにたどり着くためには、まずはそのアプリケーションが接続されているルーターへとたどり着かなければいけません。

電気信号となったデータは、まずはじめに最寄りのルーターへと移動します。
そして、宛先のIPアドレスを元に、次にどのルーターへと移動したら良いのかを尋ねるのです。

最寄りルーターと目的地ルーターが直接繋がっている場合には「このルーターに移動すればOK!」という指示が来ることでしょう。
ですが、直接繋がっていない場合はどうなるのでしょうか?
この場合は、「このルーターに移動すれば、方面は合ってる。 けどそこからの詳しい道のりは分からないから、移動後にそこのルーターで確認して!」という指示が来ることとなります。

このようにして、ネットワーク層におけるデータの転送は、各ルーターが把握しているところまでの道筋を教え合い、目的地へとパケットを転送するという仕組みをとっています。
この、正しい方向へとパケットを転送する仕組みを、ルーティングまたは経路制御と呼びます。

さぁ、目的地のルーターまで到着したら、いよいよアプリケーションにデータを届ける処理となります。

3.データを目的地内の指定アプリケーションまで届ける

データが目的地ルーターまで到達したら、いよいよ宛先アプリケーションにデータを届けます。
基本的には、ネットワークインターフェース層からアプリケーション層へと、1番とは逆の流れで届いたデータを受け渡していく中で、各層でデータ内のヘッダを読み込み、必要な処理を施す。という流れとなります。

ネットワークインターフェース層

この層では、イーサネットヘッダ内のMACアドレスを元に、接続されている各ホストが、自分宛ての通信かそうでないかを判断します。
そして、自分宛ての通信であった場合は、データを上位のネットワーク層へと引き渡すのです。

また、この層に限らず全ての層で、確認済のヘッダはデータから取り除かれるということを覚えておきましょう。

ネットワーク層

この層では、データ内のIPヘッダの情報を読み取ります。
そして、その情報から、上位層プロトコルは何を使用しているのか(=TCP通信なのか、UDP通信なのか)を判断し、適切な場所にデータを受け渡せるよう準備します。

また、細切れになって送られてくるデータを繋ぎ合わせるのも、ネットワーク層の仕事です。

このようにして再び1つに復元されたデータは、更に上位層へと渡っていきます。

トランスポート層

この層では、TCPヘッダ or UDPヘッダを読み取り、ポート番号からデータを適切なアプリケーションへとデータを受け渡す処理を行います。

また、TCP通信を行なう場合、上記にプラスして、「データが壊れていないか」「順番通りに受信できているか」などの確認を行い、問題なければデータの送信元に対して応答確認を返却するのです。
これらは、データが正常に届くことを保証するTCP通信ならではの仕組みとなります。

正しくデータを受信していた場合、いよいよアプリケーションにデータが行き渡ることとなります。

アプリケーション層

さぁ、いよいよ最終目的地に到着です。
この層では、受け渡されたデータを元に、送信側ホストから要求された操作を実行することが主な役割となるため、特にヘッダの処理等は行いません。
正常に処理できた場合、その旨を送信元アプリケーションに通知します。
また、何らかの原因で不正な処理となってしまった場合にも、その旨を送信元のアプリケーションに対して通知します。

正常な場合はそこで通信が完了、不正な場合はデータの再送or強制終了or...etcといった形で、状況に応じて次の一手が取られることとなります。

まとめ

いかがでしたでしょうか?
通信の流れは何となく掴めましたでしょうか?
本記事が、皆様の通信に対する理解の一助となれば幸いです。

重ねてになりますが、通信の流れはざっくりと

  1. 運搬に必要な情報をデータに付与し
  2. そのデータを目的地まで運び
  3. 到着したら、付与された情報を紐解きつつ、データを指定アプリケーションまで届ける
    という形となります。

今回はその大枠をまとめるために敢えて詳細は端折りましたが、本当はもっともっと細かいことがあの短い通信時間の中で行われています。

また機会があれば、それぞれの詳細もまとめてみようかなと思いますので、お楽しみに!

Discussion

MakkenMakken

Mochizukiさん
ネットワークの学習初学者です。ネットワークの通信の仕組みについて、ざっくり理解できました。ありがとうございます!

より詳細に理解したく、「2.データを目的地まで運ぶ」について下記2点ご教示頂きたく存じます。

・目的地とは、具体的にはどこを指すのでしょうか?(例えば、メールによる通信のケースだったら、送信先のメールサーバーが目的地になるのでしょうか?)
・その目的地は、アプリケーション層の何らかのコマンドをトリガーとして設定しているのでしょうか?

以上、よろしくお願い申し上げます。