どうも。つじけ(tsujikenzo)です。このシリーズでは「ノンプログラマーのためのはじめてのJava体験」を、お送りします。今日は4回目です。
前回のおさらい
前回は、「Javaでパッケージを体験しよう」ということで、パッケージ宣言やimport文を学びました。
今回は、「Javaでクライアントサーバーを体験しよう」をお送りします。
今日のアジェンダ
- クライアントサーバーとは
- クライアントとサーバーを作成しよう
- コンパイルと実行
- 多層アーキテクチャ
クライアントサーバーとは
以前、ブログで、クライアントとサーバーの、やり取りのかんたんな流れをご紹介しました。
みなさんがWEBを利用するときは、このような処理をイメージすると思います。
- パソコンやスマホなどの端末、およびブラウザがクライアントになっている
- サーバーはインターネット上のデータセンターのようなところにある
- クライアントとサーバーが、通信をしている
この通信のやりとりは、パソコン上でも再現できます。
記事にもありますが、クライアントもサーバーも、Javaで作成できるのです。
実際に、体験してみましょう。
クライアントとサーバーを作成しよう
まず、新規プロジェクト(新規フォルダのことです)を作成し、以下のようなファイル構成を作成します。
クライアントの作成
前回の復習ですが、クラスをフォルダ分けしていますので、パッケージ化します。
ファイル操作をおこなう便利なJavaのパッケージもimportしていますので、注目しておきましょう。
クラス内部のソースコードは、今回はコピペでかまわないと思います。
package client;
import java.io.*;
import java.net.*;
public class TcpClient {
public static void main(String[] args) throws Exception {
try (Socket socket = new Socket("localhost", 8001);
FileInputStream fis = new FileInputStream("client_send.txt");
FileOutputStream fos = new FileOutputStream("client_recv.txt")) {
int ch;
// client_send.txtの内容をサーバに送信
OutputStream output = socket.getOutputStream();
while ((ch = fis.read()) != -1) {
output.write(ch);
}
// 終了を示すため、ゼロを送信
output.write(0);
// サーバからの返信をclient_recv.txtに出力
InputStream input = socket.getInputStream();
while ((ch = input.read()) != -1) {
fos.write(ch);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
サーバーの作成
サーバーも同様に作成します。
復習ですが、パッケージ宣言は、ファイルの先頭で宣言しなければなりません。注意しましょう。
package server;
import java.io.*;
import java.net.*;
public class TcpServer {
public static void main(String[] argv) throws Exception {
try (ServerSocket server = new ServerSocket(8001);
FileOutputStream fos = new FileOutputStream("server_recv.txt");
FileInputStream fis = new FileInputStream("server_send.txt")) {
System.out.println("クライアントからの接続を待ちます。");
Socket socket = server.accept();
System.out.println("クライアント接続。");
int ch;
// クライアントから受け取った内容をserver_recv.txtに出力
InputStream input = socket.getInputStream();
// クライアントは、終了のマークとして0を送付してくる
while ((ch = input.read()) != 0) {
fos.write(ch);
}
// server_send.txtの内容をクライアントに送付
OutputStream output = socket.getOutputStream();
while ((ch = fis.read()) != -1) {
output.write(ch);
}
socket.close();
System.out.println("通信を終了しました。");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
テキストファイルの中身
今回は、クライアント側から、client_send.txtに書かれているテキストメッセージをサーバーに送信します。
サーバー側からは、server_send.txtに書かれているテキストメッセージをクライアントに送信します。
テキストの中身はなんでもかまいませんが、わかりやすいメッセージを保存しましょう。
実行されると、サーバーはserver_recv.txtを作成し、クライアントはclient_recv.txtを作成する、という処理です。
コンパイルと実行
コンパイル
コマンドプロンプトを起動して、ディレクトリを移動します。
TcpServer.javaと、TcpClient.javaをコンパイルします。
TcpServerの実行
TcpServerを実行します。server階層にパッケージ化したので、TcpServerの正式なクラス名はserver.TcpServerです。注意しましょう。
実行すると、「クライアントからの接続を待ちます。」と表示されます。
TcpClientの実行
そのまま、もうひとつコマンドプロンプトを起動します。(コマンドプロンプトは複数起動できます)
ディレクトリを移動します。
TcpClientを実行します。client階層にパッケージ化したので、TcpClientの正式なクラス名はclient.TcpClientです。注意しましょう。
実行確認
サーバー側のコマンドプロンプトを確認しましょう。通信が行われたことが表示されています。
プロジェクトフォルダには、テキストファイルが作成されています。
中身を確認してみましょう。間違いなくテキストを受信したようです。
コマンドプロンプトはそのまま閉じてかまいません。
多層アーキテクチャ
今回作成したプログラムは、プロジェクト内にすべてのクラスとファイルを置いてもかまいません。
しかし、あとでクライアント側にクラスを追加したいときや、サーバー側を他の人に見せたくないばあいなどは、パッケージ化して管理した方がよさそうです。
そして、この、クライアント層とサーバー層にパッケージ化した設計を、2層アーキテクチャと呼びます。
2層から3層へ
2層アーキテクチャでは、クライアント層に業務プログラムなどのアプリケーションを配置し、サーバー層にデータベースを配置していました。
やがて、クライアント層に配置されたアプリケーションへの負荷が大きくなったため、クライアント層に置いたアプリケーションをサーバーに配置する、3層アーキテクチャが登場しました。
それぞれが独立した層になっていますので、容易に変更可能です。
Webアプリケーションは、3層アーキテクチャのおかげで飛躍的な発展を遂げました。
プログラミング設計における3層アーキテクチャ
さらに、アプリケーションサーバー内部の、アプリケーション設計も大切です。
アプリケーションを効率よく開発するための設計手法が、数多く研究されています。
これまた3層アーキテクチャ(レイヤードアーキテクチャ)と呼ばれているので、少し困惑してしまうかもしれませんね。
アプリケーションアーキテクチャの3層アーキテクチャについては、別の記事でご紹介します。
まとめ
以上で、「ノンプログラマーのためのはじめてのJava体験4」をお届けしました。
わたしのようなノンプログラマーでもクライアントサーバーの体験ができると思っていませんでした。
実際に動くと、理解が進みますね。
3層アーキテクチャについても触れました。Webアプリケーションのサーバー構造と、アプリケーション設計についての3層アーキテクチャは別物ですので、区別して理解する必要があります。
次回(内容未定です)を、お楽しみに。