入社当時Webの勉強のためにWebサーバ作っていたのですが、まだできておらずWebの理解を深めなきゃという気持ちで再び取り組みはじめました。
今回は、サーバとクライアントの通信がどのように行われているのかについて書きます。
まず、クライアントとサーバを簡単に作ってみましょう。
Client.java
package client; import java.net.Socket; public class Client { public static void main(String[] args) throws Exception { try(Socket socket = new Socket("localhost", 8001)) { } catch (Exception e) { e.printStackTrace(); } } }
Server.java
package server; import java.net.ServerSocket; import java.net.Socket; public class Server { public static void main(String[] args) throws Exception { try(ServerSocket serverSocket = new ServerSocket(8001)) { System.out.println("クライアントからの接続待ち。"); Socket socket = serverSocket.accept(); System.out.println("クライアントからの接続!"); socket.close(); } catch (Exception e) { e.printStackTrace(); } } }
サーバを実行した後に、クライアントを実行するとクライアントからサーバへ通信しにいきます。クライアントからサーバで通信するまでに何が行われているのか説明します。流れは、次の通りです。なお、上記のプログラムでは3はやっておりません。
1.ソケットを作る(ソケット作成フェーズ)
まず、サーバがソケットを作成します。ソケットとは、パイプの両端にある出入り口のことです。その時に上記のServer.javaは、8001番ポートで待ち受けています。(「クライアントからの接続を待ちます」と出力)
ソケットができたら、ディスクリプタ(ソケットに割り当てられた番号のようなもの)が返ってきます。アプリケーションはこれを受け取ってメモリに記憶します。ディスクリプタでソケットを識別しています。
2.サーバ側のソケットにパイプをつなぐ(接続フェーズ)
「new Socket("localhost", 8001)」でストリームソケットを作成し、指定されたホスト上の指定されたポート番号に接続します(「クライアント接続」と出力)。繋ぎたいソケットを正確に取得するために、IPとポート番号が必要です。(考え方は手紙の宛名面と同じです。「住所=IPアドレス、宛名=ポート番号」)
3.データを送受信する(送受信フェーズ)
ネットワークを通してデータがサーバに送られます。そして、サーバ側からレスポンスが返ってきます。受信したメッセージを格納するためのメモリ領域を受信バッファと呼びます。
4.パイプを外してソケットを抹消する(切断フェーズ)
繋がっていたパイプを外します。クライアントでもサーバでもどちらから外しても構いません。その後、ソケットを抹消します。
ソケットについてもやもやしていたので少し解消できました!!!