ソケットとは
ソケットは「一般にクライアントとサーバーの対話で使用される仕組み」のことです。
いわば、アプリケーション(プログラム)とネットワークをつなげる「接続口」のことで、IPアドレスとアプリケーションを識別するポート番号の組み合わせとも考えることができます。
通常のシステム構成では、一方のマシンにサーバーを、 もう一方のマシンにクライアントを置きます。 クライアントはサーバーに接続して情報を交換し、その後切断します。
ソケットには定まっているのイベントの流れがあります。 コネクション型クライアント/サーバー・モデルでは、 サーバー・プロセス上のソケットはクライアントからの要求を待ちます。 これを行うため、サーバーはまず、 クライアントがサーバーを探せるようにアドレスを確立 (バインド) します。 アドレスが確立されると、サーバーはクライアントがサービスを要求してくるのを待ちます。 クライアントとサーバーとの間のデータ交換は、 クライアントがソケットを経由してサーバーに接続しているときに行われます。 サーバーは、クライアントの要求を実行し、クライアントに応答を送信し返します。
下記にソケット通信の参考ページを示します。
下記の記事も非常にわかりやすいです。
上記の流れが、コネクション型ソケットの一般的なイベント・フローになりますが、具体的にソケットを使った通信の流れについてそれぞれ見ていきましょう。
1.ソケットを作る (socket() API)
→ 通信をするための「通路」を用意します。これは電話をかけるために携帯電話を手に取るイメージです。
2.ソケットに名前をつける (bind() API)
→ サーバー側が「私はここにいますよ」と言うために、IPアドレスとポート番号(番号)をセットします。電話番号を自分の電話に割り当てるようなものです。
3.電話をかける準備をする (listen() API)
→ サーバーが電話の着信を待つ状態にします。電話を「待ち受けモード」にするような感じです。
4.クライアントが接続する (connect() API)
→ クライアント(電話をかける側)が、サーバーに「接続したい!」とリクエストを送ります。これが電話をかける行為に似ています。
この部分でTCPの場合は、「TCPハンドシェイク」を行いTCP接続を確立します。
5.サーバーが電話を受ける (accept() API)
→ サーバーがクライアントのリクエストを受け取って、通信を開始します。電話に出ることです。
6.実際にデータをやり取りする (send(), recv() などのAPI)
→ クライアントとサーバーがデータを送ったり受け取ったりします。これは電話で会話をするようなものです。
7.電話を切る (close() API)
→ 通信が終わったら、ソケットを閉じて「電話を切る」ようにします。
つまり、ソケット通信は「サーバーが電話をかけられる状態にして、クライアントが電話をかけて、会話(データ通信)をして、最後に電話を切る」という流れになります。
TCP/IPの参照モデル
アプリケーション層とその下位のトランスポート層/ネットワーク層との関係性を見ていきましょう。
通信モデルの中でアプリケーション層とトランスポート層の間に「ソケットAPI」というものが有ります。
ソケット API は、 通信モデルの中の層ではありません。ソケット API を使用することにより、 アプリケーションは一般的な通信モデルのトランスポート層やネットワーク層と対話することができるようになるわけです。 以下の図の矢印は、ソケットの位置とソケットが提供する通信層とを示しています。