ネットワークソケットとは?ポートとの違いを解説

混同されがちなソケットとポートの違いを、ステップを追って基礎から整理します。

  1. ソケットとは何か

    ソケットとは、IPアドレス・ポート番号・プロトコル(TCPまたはUDP)の組み合わせでできる、通信の片方の端点のことです。電話に例えると、IPアドレスは建物の住所、ポート番号はその建物内の内線番号、ソケットは実際に通話がつながっている1本の回線にあたります。

  2. ポートとソケットの違い

    ポート番号は「どのサービスに接続するか」を示す単なる数字(0〜65535)ですが、ソケットはそのポート番号に実際のIPアドレスとプロトコルまで組み合わせてできる、具体的な接続そのものを指します。同じ80番ポートでも接続してきたクライアントのIPごとに別々のソケットが作られるため、1台のサーバーに同時に多くの人が接続できるのです。

  3. ソケットペアで接続を区別する

    1つのTCP接続は「自分のIP:自分のポート」と「相手のIP:相手のポート」からなるソケットペアによって一意に識別されます。これにより、サーバーは同じ80番ポートに何千人が同時に接続していても、どのソケットペアがどの利用者のものかを正確に区別できます。

  4. TCPソケットとUDPソケットの違い

    TCPソケットは電話をかけるように先に接続を確立してから(スリーウェイハンドシェイク)、順序と到達を保証しながらデータをやり取りする方式です。一方UDPソケットは事前に接続を確立せず、はがきを送るようにその都度データを送信します。ウェブサイトの閲覧のように正確さが重要な場合はTCP、オンラインゲームやビデオ通話のように速度が重要な場合はUDPベースのソケットがよく使われます。

  5. ウェルノウンポートと一時ポート

    サーバーが使う80番(HTTP)や443番(HTTPS)のようなポートは、誰でも接続先がわかるように定められた「ウェルノウンポート」です。一方、自分の端末(クライアント)がサーバーに接続する際に使うポートは、その都度OSが自動的に割り当てる一時ポート(おおむね49152〜65535の範囲)で、利用者が意識する必要はありません。

  6. ソケットアドレスの表記法

    ソケットアドレスは一般的に「IPアドレス:ポート番号」の形で表記されます。例えば192.168.0.10:8080は、192.168.0.10という機器の8080番ポートを指すソケットアドレスで、サーバーの設定ファイルや開発者向けツールの画面でよく見かける表記です。

  7. リスニングソケットと確立済みソケット

    サーバー側のプログラムが特定のポートで新しい接続を待っている状態をリスニングソケットと呼び、クライアントと実際に接続が確立してデータをやり取りしている状態を確立済み(Established)ソケットと呼びます。netstatのようなネットワーク診断コマンドを使えば、現在どのソケットが待受け中で、どのソケットが接続済みかを直接確認できます。

  8. ファイアウォールが制御しているのも結局はソケット

    ファイアウォールのルールで「特定のポートをブロックする」というのは、実際にはそのポートで新しいソケット接続が作られること自体を防いでいるということです。ソケットの概念を理解すると、ポートフォワーディングやファイアウォールのルール、プロキシの設定といった様々なネットワークの仕組みが、結局は同じ原理の上で動いていることが見えてきます。

  9. ポート番号の3つの範囲

    IANAはポート番号を、ウェルノウンポート(0〜1023)、登録済みポート(1024〜49151)、動的・プライベートポート(49152〜65535)に分けています。ウェルノウンポートにはSSHの22番、メール転送の25番、DNSの53番、ウェブの80番と443番など、基本的なサービスが割り当てられています。クライアントが使う一時ポートはOSが動的な範囲から選び、Linuxの既定ではIANAの範囲ではなく32768〜60999が使われます。

  10. TCPサーバーのソケットの一生

    典型的なサーバーは、ソケットを作成し、アドレスとポートに結び付け(bind)、listenで接続の受付を開始し、クライアントが来るたびにacceptを呼びます。acceptはその会話専用の新しいソケットを返し、元のリスニングソケットは待ち続けます。やり取りが終わると双方がソケットを閉じ、接続は終了処理の状態を経て消えます。

  11. クライアント側の手順

    クライアントはソケットを作り、必要ならbindし、サーバーのアドレスとポートを指定してconnectを呼びます。TCPではこれによりスリーウェイハンドシェイクが始まります。送信元ポートが指定されていなければOSが選び、接続後は片方が閉じるまで双方が送受信できます。UDPではconnectを省いて、宛先を指定してデータグラムを送るだけで済み、ハンドシェイクもありません。

  12. TIME_WAITと閉じたソケットがしばらく残る理由

    TCP接続が閉じられたあと、先に閉じた側はしばらくTIME_WAIT状態を保ちます。古い接続から遅れて届いたパケットを、新しい接続のものと取り違えないようにするためです。忙しいシステムではこうしたソケットが大量に溜まることがあります。これは安全のための仕組みなので、安易に待ち時間を短くすると、原因の分かりにくいエラーを招くことがあります。

  13. 同じマシン内で使うローカルソケット

    すべてのソケットがIPアドレスを使うわけではありません。UNIXドメインソケットは、ネットワークアドレスの代わりにファイルシステム上のパスで同じコンピューター内のプログラム同士をつなぎ、ネットワークスタックの多くの処理を省けるため、データベースやウェブサーバーのローカル通信でよく使われます。Windowsにも似た仕組みがあります。プログラミング上の扱いが似ているため、同じ考え方がそのまま通用します。

  14. ソケットAPIの由来

    ソケットのプログラミングインターフェースは1980年代初めにBerkeley系のUNIXで導入され、ほぼすべてのOSに広がりました。そのため、socket、bind、listen、accept、connect、send、recvといった関数名は、C言語でもPythonでも他の多くの言語でもほとんど同じです。WindowsではWinsockという互換の仕組みが採用されました。

名前は似ているが別物のWebSocket

「WebSocket」は名前こそ似ていますが、このページで説明したOSレベルのソケットとは別物で、ブラウザとサーバーが持続的に双方向通信を行うために作られた、独立したアプリケーション層のプロトコルです。WebSocketの接続自体は、内部的には通常のTCPソケットの上に構築されています。

ソケット・ファイアウォール・ポートフォワーディングは同じ考え方の別の側面

ファイアウォールが特定のポートをブロックするというのは、実際にはそのポートで新しいソケットが作られるのを防いでいるということであり、ポートフォワーディングはルーターに届いたソケット接続をネットワーク内の特定の機器に転送する仕組みです。ソケットの概念が腑に落ちると、これらの関連する用語が別々に覚えるべきルールではなく、つながった一つの仕組みだと見えてきます。

netstatやssの出力の読み方

Windowsではnetstat -an、Linuxではss -tanを実行すると、ローカルアドレス、リモートアドレス、状態を持つソケットの一覧が表示されます。状態がLISTENの行はリスニングソケットで、サーバーが待ち受けているアドレスを示します。0.0.0.0や[::]はすべてのインターフェースで待ち受けていることを、127.0.0.1はそのマシン内だけで待ち受けていることを意味します。ESTABLISHEDの行は進行中の会話で、それぞれがローカルとリモートの端点の固有の組み合わせです。TIME_WAITやCLOSE_WAITは接続の終了処理中を示します。1つのプログラムが持つCLOSE_WAITが大量にある場合は、そのプログラムが接続を正しく閉じていない、サーバーコードによくあるバグの可能性があります。こうした状態を知っておくと、サービスがそもそも待ち受けているかどうかを判断しやすくなり、つながらないときに最初に確認すべき点が分かります。

ソケットを扱うときのよくある間違い

初心者は、接続の失敗とポートが閉じていることを混同しがちです。接続拒否は、マシンが応答したがそこで待ち受けているものがなかったことを意味し、タイムアウトはファイアウォールがパケットを捨てたか、ホストに到達できないことを意味するのが普通です。また、サーバーを127.0.0.1にバインドしたため他のマシンから届かない、という落とし穴もあります。TCPはメッセージではなくバイトの流れだということを忘れると、1回の送信が2回の受信に分かれたり、2回の送信が1回にまとまって届くバグが起きます。さらに、ポートが使用中というエラーは、別のプログラムか、前回の実行によるTIME_WAITがそのアドレスを保持していることがほとんどです。

よくある質問

ソケット番号は自分で決める必要がありますか?

いいえ。サーバー側のウェルノウンポート(80番や443番など)はプログラムや管理者が指定しますが、クライアントとして使う一時ポートはOSが自動的に割り当てるため、利用者が設定する必要はありません。

サーバーでソケットが足りなくなることはありますか?

はい。非常に短い時間に大量の接続の確立と切断を繰り返すサーバーでは、一時ポートが一時的に不足する「ソケット枯渇」と呼ばれる現象が起こることがあります。この場合、サーバー側の接続の再利用(キープアライブ)設定を調整することで緩和されることがあります。

1台の機器にポートはいくつありますか?

TCPとUDPそれぞれに65,536個(0〜65535)の番号があります。0番は予約されており通常の通信には使われません。実際にはすべてを使うわけではなく、大半はその時点で使われていません。

2つのプログラムが同じポートで待ち受けることはできますか?

同じアドレスとプロトコルでは通常はできず、後から起動したほうがアドレス使用中のエラーになります。負荷分散のために複数のプロセスが同じポートで受け付けるオプションもありますが、明示的に有効にする必要があります。TCPとUDPはポートの空間が別なので、一方のプログラムがTCPの53番、別のプログラムがUDPの53番を使うことは可能です。

ソケットとコネクションは同じものですか?

近いものですが同一ではありません。ソケットはプログラムが持つ片方の端点で、コネクションは2つの端点の組み合わせです。リスニングソケットは、クライアントが来るまでコネクションを持ちません。