DIVX テックブログ

catch-img

通信の流れを実際にコマンドを打って確かめてみた

目次[非表示]

  1. 1.はじめに
  2. 2.OSI参照モデル
    1. 2.1.OSI参照モデルが誕生した理由
    2. 2.2.OSI参照モデル7つのレイヤー
  3. 3.OSI参照モデルは普及せず、TCP/IPが普及していく
  4. 4.TCP/IP4階層モデル
  5. 5.TCP/IP4階層モデルとOSI参照モデルのレイヤーの関係
    1. 5.1.4つのレイヤー
  6. 6.TCP(Transmission Control Protocol)
  7. 7.IP(Internet Protocol)
    1. 7.1.IPアドレス(Internet Protocol Adress)
  8. 8.ARP(Address Resolution Protocol)
    1. 8.1.MACアドレス
  9. 9.ICMP(Internet Control Message Protocol)
  10. 10.UDP(User Datagram Protocol)
  11. 11.TCP/IP4階層モデルを図で確認してみよう
  12. 12.コマンドを使ってTCP/IPの流れを見てみよう
    1. 12.1.ping
    2. 12.2.ip address show
    3. 12.3.ネットワークインターフェイスとは
    4. 12.4.仮想NIC(Network Interface Card)とは
    5. 12.5.tcpdump
  13. 13.おわりに

はじめに

はじめまして。divxのエンジニアの前田です。 今回は、エンジニアの基本の「き」である通信の仕組みについて書いて行こうと思います。 この記事を書こうと思ったきっかけは、個人的につよつよエンジニアは基本を大切にしている共通点があると思ったからです。

「エンジニアとしての基本ってなんだろう。」と考えた結果、 「どうやって通信が動いているのかが、基本中の基本ではないか!」 と考え、まずは通信の流れを知ろうと考えました。

どうせ学ぶなら、文字を読むだけの受動的な内容ではなく、手を動かす能動的な学びが良いと思いました。 実際にUbuntuというOSで通信の動きを見て、学んでいきたいと思います。 この記事を読んで基本が大切なんだと気づいてくれればと思います。

OSI参照モデル

ネットワークの動きを知るためには、まずはOSI参照モデルを知る必要があります。 OSI(Open Systems Interconnection)参照モデルとは、国際標準化機構(ISO)により策定されたコンピューターなどの通信機器の流れを階層構造に分割したモデルです。 OSI参照モデルでは、通信約束事を7つの階層に分けており、それぞれの階層で行われる通信機能を定義しています。

この通信の約束事のことを「プロトコル」と呼びます。 プロトコルの集まりが「プロトコルスタック」です。 そして、階層のことを「レイヤー」と読んでいます。

OSI参照モデルが誕生した理由

そもそも、OSI参照モデルが策定される以前は、メーカは自社製品同士でしか通信できないプロトコルスタックをそれぞれ作っていました。 しかしネットワークが普及するにつれ、異なるメーカーの機器との接続の要望が増えたため、異なるメーカーの通信を実現するための設計方針(OSI)が1984年に策定されました。

さらに、レイヤーごとにプロトコルを切り分けることで、各プロトコルの役割が明確になります。 問題が起きた時に、どこに問題が起きているかが分かりやすくなります。

OSI参照モデル7つのレイヤー

以下が、OSI参照モデルの7つのレイヤーになります。 (L1、2...はレイヤー1、2...の略)


レイヤー

名前

役割

L7

アプリケーション層

アプリケーション間でのルール

L6

プレゼンテーション層

ユーザーが見て触れるデータのルール

L5

セッション層

アプリケーション間の接続のルール

L4

トランスポート層

通信の信頼性に関するルール

L3

ネットワーク層

End to Endでの通信に関するルール

L2

データリンク層

ルーターなどの通信に対して何らかの能動的な役割を

果たす機器のルール

L1

物理層

機器や電気信号に関するルール

OSI参照モデルは普及せず、TCP/IPが普及していく

OSI参照モデルは運用が複雑なことと、各メーカも導入にコストがかかりなかなか流通しませんでした。 さらに1990年代にTCP/IPが急速に普及したことで、格メーカーはTCP/IPを実装した製品をリリースしていきました。 そのため、世の中にTCP/IPが広まり、OSI参照モデルが世界標準になることはありませんでした。 しかし、根本的な考え方はOSI参照モデルを使用しており、通信をする上で必ず理解する必要があります。

TCP/IP4階層モデル

現在、通信の標準になっているのがTCP/IP4階層モデルです。 日常生活では、あまり意識されることはありませんが通信を行うために無くてはならない存在です。

TCP/IP4階層モデルは、主にIETF(InternetEngineeringTaskForce)という組織が標準化の主体になっています。 RFC(RFC791)という技術書を発行することで、プロトコルの使用を公開しています。

TCP/IPはインターネットのデファクトスタンダード(事実上の標準)な通信プロトコルです。 TCP/IP4階層モデルではTCPとIPというプロトコルを中心に4つのレイヤーで定義されています。 TCP/IP4階層モデルもOSI参照モデルと同じように、それぞれの役割に応じて4つのレイヤーに分かれています。

TCP/IP4階層モデルとOSI参照モデルのレイヤーの関係

TCP/IP4階層モデルもレイヤーという考え方を持っていますが、OSI参照モデルのレイヤーとは別物です。 OSI参照モデルは、ISOという団体が策定したものです。 TCP/IP4階層モデルは、IETFが主体になり策定されています。

4つのレイヤー

以下がTCP/IP4階層モデルの4つのレイヤーになります。

レイヤー
名前
役割
L4

アプリケーション層

アプリケーションごとの固有のルール。HTTP,FTP,SMTP,SSHなどのプロトコルにより、通信の機能が実現される

L3

トランスポート層

データ転送の信頼性を確保するためのルール。TCP,UDPが代表的なプロトコルになる。

L2

インターネット層

ネットワーク間のEnd to Endでの通信に関してのルール。IPが代表的なプロトコルになる。IPアドレスを割り当てることができる。

L1

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

ネットワーク上での通信、ハードウェア仕様などのルール。MACアドレスなどを割り当てることができる。

TCP/IP4階層モデルはOSI参照モデルでいう「物理層」を重要視していません。 なので、物理層とデータリンク層を合わせた形で「リンク層」と呼んでいます。 ユーザーが触れるものを、「アプリケーション層」とまとめています。

では、ここから5つTCP/IP4階層モデルを理解するための重要なプロトコルの解説をします。

TCP(Transmission Control Protocol)

TCPとはトランスポート層にあたるプロトコルです。 信頼性は高いが転送速度が遅いという特徴があります。 信頼性を高めるために、送信元&宛先の双方で状況を確認しながら通信を行います。 この、双方に状況を確認する通信を「コネクション型」と言います。


IP(Internet Protocol)

インターネット層で中心的な役割を担うプロトコルです。 特徴として、通信状況やエラーの確認をせずに通信を行います。 通信状況やエラーの確認をせずに行う通信を「コネクションレス型」といいます。 IPアドレスを使用して、通信に必要な経路を判断しています。

IPアドレス(Internet Protocol Adress)

IPと呼ばれるプロトコルを使うネットワークにおいて、各コンピューターを識別するために、コンピューターへ付与する番号の列です。 ネットワークの世界における住所のようなものです。 世界中で重複しないように設定されています。

ARP(Address Resolution Protocol)

IPアドレスに紐づくMACアドレスを調べてくれます。 IPアドレスからMACアドレスを調べる処理を、アドレス解決と呼びます。

MACアドレス

パソコンやルータなどに登録されている番号です。 機器同士で通信するために利用されます。

ICMP(Internet Control Message Protocol)

エラー通知や問い合わせ情報を転送してくれます。 IPはコネクションレス型通信のため、転送に失敗したとしても「失敗した」と検知することができません。 そのため、ICMPがそれを補う役割を担ってくれます。

UDP(User Datagram Protocol)

TCPと違い、スピード重視のプロトコルです。 品質は重要視せず、スピード重視なので届いたときにデータの欠損などが起きます。 動画ストリーミングなど、分割の不要なデータの転送などに大活躍してくれます。

TCP/IP4階層モデルを図で確認してみよう

TCP/IP4階層モデルでは、さまざまなプロトコルが相互に関係しながら送受信しています。 OSI参照モデルとは違い、シンプルな構造だから世界標準になったのかなと個人的には思っています。

以下の図が、レイヤーごとにプロトコルを記載したものになります。 

TCP/IP4階層モデルを図で確認してみよう

コマンドを使ってTCP/IPの流れを見てみよう

ここからは、実際に手を動かしてTCP/IPを動かしてみます。

ping

通信の疎通を確認するコマンドです。 ICMPを利用し、エコーリクエストとエコーリプライというメッセージをやり取りします。 現実世界で例えると「こんにちはー!」と返して、応答してくれるかを見るコマンドになっています。

ubuntu@primary:~$ ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=60 time=14.4 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=60 time=18.0 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=60 time=16.0 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=60 time=10.9 ms
^C
--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 5199ms
rtt min/avg/max/mdev = 10.932/14.977/17.978/2.278 ms

細かく見ていきましょう。

64 bytes from 8.8.8.8:

この部分は、8.8.8.8というIPアドレスを持った通信相手から応答があったということを教えてくれています。 ちなみに、8.8.8.8というのはGoogleが公開しているパブリックDNSサーバーのIPアドレスになります。

icmp_seq=1 ttl=60

icmp_seq=1は応答回数になります。 つまり、今回4回応答があったということになります。 ttlはTime To Liveという、通信の有効期限のことです。無限ループを防ぐために通信にはTTLというものが設定されています。

time=14.4 ms

これは応答が届くまでにかかった時間です。 14.4ms応答までにかかったということです。

--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 5199ms
rtt min/avg/max/mdev = 10.932/14.977/17.978/2.278 ms

最後のこの部分は統計情報になります。 応答が届いた割合や、応答が届くまでにかかった時間に関する統計量が表示されています。 今回の場合、4回要求を送り、4回応答が返って来て、途中でロスしたものは0%です。と教えてくれています。 最後の部分は、最小時間/平均/最大時間/標準偏差を教えてくれています。

ip address show

まずはIPアドレスを見てみましょう。 IPアドレスを見るためには、以下のコマンドを使います。

ip address show

これでIPアドレスを含むネットワークデバイスの一覧を表示できます。 ネットワークデバイスとは、ネットワーク接続に必要な機器のことです。

しかし、ここでいうネットワークデバイスとは、デバイス名、IPv4アドレス、IPv6アドレス、MACアドレスのことを指します。

ubuntu@primary:~$ ip address show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: enp0s1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:ce:0d:ca brd ff:ff:ff:ff:ff:ff
    inet 192.168.64.8/24 brd 192.168.64.255 scope global dynamic enp0s1
       valid_lft 83694sec preferred_lft 83694sec
    inet6 fded:6b40:e401:520d:5054:ff:fece:dca/64 scope global dynamic mngtmpaddr noprefixroute 
       valid_lft 2591947sec preferred_lft 604747sec
    inet6 fe80::5054:ff:fece:dca/64 scope link 
       valid_lft forever preferred_lft forever

コマンドを実行すると、たくさん情報が出てきましたね。 どこにIPアドレスがあるか確認してみましょう。

 inet 127.0.0.1/8 scope host lo

まずこちらは、自身のネットワークインターフェイスのIPアドレスを表示してくれています。

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

ネットワークを利用するため必要な機器のことです。 レイヤー1でルールが定義されています。 今回説明しているネットワークインターフェイスは、Ubuntuで仮想的に用意されているものになります。 この自分自身を表すIPアドレスを、ループバックアドレスと言います。 動作確認なので、自分自身だけに関わる通信をしたいときにループバックアドレスは使用されます。

inet 192.168.64.8/24 brd 192.168.64.255 scope global dynamic enp0s1

この部分は、仮想NICのIPアドレスになります。

仮想NIC(Network Interface Card)とは

そもそもNICとは、ルーターにLANケーブルを指すために部品のことです。 インターネットを使用する時、必ず必要な部品になっています。 今回、UbuntuOSの仮想環境でコマンドを動かしています。 そのため、コンピューターの中に擬似的に再現したNICが仮想NICになります。


次は、通信の流れを見てみましょう。

tcpdump

通信の流れをみるためには、下記のコマンドを使います。

sudo tcpdump -tn -i any icmp

tcpdumpに記載しているオプションの補足をしておきます。

-t 時刻に関する情報を出力しないようにする。
-n IPアドレスをそのまま表示するために使用するオプションです。オプションをつけないと、DNSのドメイン名が表示されます。
-i 通信するネットワークインターフェイスを指定できます。今回anyをつけているので、すべてを対象にしています。


では、実行してみましょう

sudo tcpdump -tn -i any icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes

実行すると、実行の待ちの状態になります。 新しいターミナルを開き、もう一度8.8.8.8をpingします。

ubuntu@ubuntu:~$ ping -c 3 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=60 time=19.3 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=60 time=16.7 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=60 time=10.6 ms

--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2095ms
rtt min/avg/max/mdev = 10.572/15.523/19.254/3.648 ms

ちなみに -c オプションはpingの応答回数をしているオプションです。 今回だと、「3回8.8.8.8に通信ができているかを確認して。」という意味になります。 tcpdumpしたターミナルに戻ると以下のように変化していると思います

ubuntu@ubuntu:~$ sudo tcpdump -tn -i any icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes
IP 192.168.64.3 > 8.8.8.8: ICMP echo request, id 2, seq 1, length 64
IP 8.8.8.8 > 192.168.64.3: ICMP echo reply, id 2, seq 1, length 64
IP 192.168.64.3 > 8.8.8.8: ICMP echo request, id 2, seq 2, length 64
IP 8.8.8.8 > 192.168.64.3: ICMP echo reply, id 2, seq 2, length 64
IP 192.168.64.3 > 8.8.8.8: ICMP echo request, id 2, seq 3, length 64
IP 8.8.8.8 > 192.168.64.3: ICMP echo reply, id 2, seq 3, length 64

これも細かく確認していきましょう。

IP 192.168.64.3 > 8.8.8.8:

送信元の192.168.64.3が8.8.8.8に対して通信を送ったよという表記になります。

IP 8.8.8.8 > 192.168.64.3:

逆にこれは、8.8.8.8が192.168.64.3に通信を返したよという表記です。 これにより、通信を送って返って来たことが確認できます。
次の列を見てみましょう。

ICMP echo request, id 2, seq 1, length 64
ICMP echo reply, id 2, seq 1, length 64

先頭にICMPと記載されています。 実はPingコマンドは、IPとICMPの組み合わせで通信のやり取りが行われています。 送信元の192.168.64.3からICMPでエコーリクエストを送り、相手からエコーリプライが戻ってくることで疎通を確認しています。 さらに、エコーリプライが返ってきた時に192.168.64.3と8.8.8.8のIPアドレスが入れ替わっています。

IP 192.168.64.3 > 8.8.8.8: ICMP echo request
IP 8.8.8.8 > 192.168.64.3: ICMP echo reply

pingとtcdumpで、IPパケットの流れを見ることができました。

おわりに

通信の流れという、基本の「き」を知ることで、フルスタックで活躍できるエンジニアに近づいたと思っています。 私自身もこの記事の執筆で、基本部分を振り返ることができました。 改めて調査などを行い、「知っているつもり」だった部分にも気づくことができました。 基本に立ち戻ることの大切さを分かってもらえたなら幸いです。 今回は以上になります。最後まで目を通して頂きありがとうございます。

divxでは一緒に働ける仲間を募集しています。
興味があるかたはぜひ採用ページを御覧ください。
​​​​​​​

  採用情報 | 株式会社divx(ディブエックス) 可能性を広げる転職を。DIVXの採用情報ページです。 株式会社divx(ディブエックス)



お気軽にご相談ください


ご不明な点はお気軽に
お問い合わせください

サービス資料や
お役立ち資料はこちら

DIVXブログ

テックブログ タグ一覧

採用ブログ タグ一覧

人気記事ランキング

GoTopイメージ