Network
299
どのような問題がありますか?

この記事は最終更新日から1年以上が経過しています。

投稿日

更新日

127.0.0.1とlocalhostと0.0.0.0の違い

それぞれの意味について

127.0.0.1

127.0.0.1はループバックアドレスの一つであり、同時に127.0.0.1に対応する仮想的なネットワーク・インターフェースを表します。
ループバックアドレスは自分自身を表す特別なIPアドレスのことです。
ループバックアドレスは同一ホスト内でしか通信を行いません。

localhost

127.0.0.1を表すホスト名のことです。
127.0.0.1とほぼイコールなので当たり前ですが、こちらも同一ホスト内でしか通信を行いません。
何らかの開発用サーバを立ち上げた際に、ブラウザにlocalhost:8080といったアドレスを入力することがあるかと思いますが、それはこのlocalhostです。

0.0.0.0

前者2つとだいぶ異なり、すべてのネットワーク・インターフェースを表します。
ワイルドカードのようなもので、すべての通信を表します。
こちらは別ホストからでもアクセスすることが可能です。

ちょっと試してみる

pythonでいくつか試してみます。

まず雰囲気作りのために簡単なコンテンツを用意します。

$ mkdir test && cd test
$ echo "<h1>Hello<h1>" >> index.html

次に以下のコマンドで開発用サーバを起動します。

$ python3 -m http.server 8000

この状態でブラウザでlocalhost:8000にアクセスすると、Helloの文字を見ることができます。

ところでpythonの開発用サーバの出力1行目を見てみましょう。

$ python3 -m http.server 8000
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

on 0.0.0.0 port 8000という記述は、0.0.0.0の8000ポートに対して開発用サーバが起動していることを表します。
0.0.0.0はワイルドカードのようなものでした。
つまりこれは、すべてのネットワーク・インターフェースの8000ポートに対して、サーバが起動している状態です。
この状態ではネットワークが繋がってさえいれば、remoteからアクセスすることが可能です。

次に127.0.0.1を指定して開発用サーバを起動してみましょう。
--bindオプションを利用することで指定できます。

$ python3 -m http.server --bind 127.0.0.1 8000
Serving HTTP on 127.0.0.1 port 8000 (http://127.0.0.1:8000/) ...

127.0.0.1の8000ポートに対してサーバが起動している状態です。
この状態でも同一ホストでブラウザにlocalhost:8000を指定すればHelloが表示されます。
ただしlocalhostはループバックアドレスです.
なので、この状態では仮にネットワークが繋がっていてもremoteからアクセスすることができません。

最後にlocalhostを指定してみましょう。

$ python3 -m http.server --bind localhost 8000
Serving HTTP on 127.0.0.1 port 8000 (http://127.0.0.1:8000/) ...

1行目の出力が127.0.0.1を指定した場合と全く一緒です。
これはlocalhostが127.0.0.1のホスト名であるためです。

bindとは

別ウィンドウを立ち上げて、例えば以下のコマンドを2回叩いてみます。

# わかりやすさのために0.0.0.0を明示
$ python3 -m http.server --bind 0.0.0.0 8000

するとあとから起動した方では以下のようなエラーになります。

OSError: [Errno 48] Address already in use

一方で例えば、以下2つであれば同時に走らせてもエラーにはなりません。
この状態でブラウザからlocalhost:8000にアクセスすると、bindにlocalhostを指定した方のコンソールにアクセスログが出力されます。

$ python3 -m http.server --bind localhost 8000
$ python3 -m http.server --bind 0.0.0.0 8000

1つめと2つめの違いは、IPとポートの組み合わせが一致しているかどうかです。
私は、マシンに8000ポートは一つしかない、と思っていたことがありました。
ただこれは誤りで、実際は一つのネットワーク・インターフェースにつき一つです。
このネットワーク・インターフェースには、127.0.0.1のような仮想的なものも含まれます。
そしてマシンは複数のネットワーク・インターフェースを持つことができ、複数のIPアドレスを持つことが出来ます。

bindオプションは、ネットワークインターフェース(に紐づくIP)とそのポートを指定することで、そのネットワーク・インターフェースを通ってきたアクセスのみを識別して処理を行うことができます。
localhostや0.0.0.0といったちょっと特別なIPを例に挙げましたが、もちろんマシンが持つローカルIPアドレスをbindに指定することもできます。

この仕組はpythonに限った話ではなく、一般的にbind addressと呼ばれます。

参考

ユーザー登録して、Qiitaをもっと便利に使ってみませんか。
  1. あなたにマッチした記事をお届けします
    ユーザーやタグをフォローすることで、あなたが興味を持つ技術分野の情報をまとめてキャッチアップできます
  2. 便利な情報をあとで効率的に読み返せます
    気に入った記事を「ストック」することで、あとからすぐに検索できます
1ain2

コメント

この記事にコメントはありません。
あなたもコメントしてみませんか :)
ユーザー登録
すでにアカウントを持っている方はログイン
299
どのような問題がありますか?
ユーザー登録して、Qiitaをもっと便利に使ってみませんか

この機能を利用するにはログインする必要があります。ログインするとさらに下記の機能が使えます。

  1. ユーザーやタグのフォロー機能であなたにマッチした記事をお届け
  2. ストック機能で便利な情報を後から効率的に読み返せる
ユーザー登録ログイン
ストックするカテゴリー