Tagbangers Blog

サーバ関連の技術をJavaで実装する

こんにちは、藤岡です。

先週はブログの更新ができなかったので、その内容と合わせて共有していきたいと思います。

先週と今週で、出していただいた課題がほとんど終わったので、達成感がありました。

どういう内容のものを作って、何を学ぶことができたか、それぞれ紹介していきます。


lsコマンド

先週、長い間格闘していたlsコマンドが完成しました → 完成版

前回でほぼ完成していたのですが、より本来のlsコマンドに近づけるために、パスを渡してそのディレクトリ配下のファイル(ディレクトリ)名を表示させるということを実装しました。

具体的には、絶対パスが指定された時と、相対パスが指定された時で処理をわけました。

一応説明しておくと、絶対パスというのは先頭が「/」か「~」で始まり、カレントディレクトリに関わらず、ルートディレクトリを参照するものです。一方の相対パスというのは、カレントディレクトリを基点としており、そのままディレクトリ名などを指定するものです。

また、最初はArrayListでファイルを保持しておいたのですが、そのままだと「順序を指定していない時にどのような自然順序付けがなされているのか曖昧である」という問題を指摘していただいたので、TreeSetでファイルをもち、compareToメソッドをオーバーライドすることでその問題を解決しました。

このプログラムを作る上で思ったのは、パスを指定しない場合とあまり変わらず、そこまで複雑なプログラムを組む必要がないということでした。

パスを指定する時、「./」や「../」といった短縮系で表されるものがあり、それらの処理も実装する必要があったので頭を悩ませていましたが、パスを渡すだけできちんと取得できていたので、驚きました。コンピュータはかなり頭がよく、指示さえ間違えなければ要領よく仕事をしてくれるのだということを改めて実感しました。


Chatアプリ

このサイトを参考にして、Javaでチャットアプリを作りました。 → 完成版

この課題に取り組む上で重要な概念は、ThreadとSocketで、簡単に説明すると、Threadは「複数の処理を同時に行う時に並列的に処理させるもののこと」で、Socketは「2つのマシン間で通信行う際の基点のようなもの」です。

これらの概念について理解するのは難解であるけど、特にThread(並行処理)の理解は極めて重要であるということなので、これからプログラムを組んでいく上で意識して使っていくようにしたいです。

また、このプログラムでは自分でポート番号を指定してp2pのやりとりをするのですが、このポート番号をどう設定するのかも大切になってきます。

このサイトの説明がわかりやすかったのですが、簡潔に説明すると、0~65535までポート番号を指定することができて、特に0~1023までをウェルノウンポート番号と言います。これはhttpやhttpsなど、よく使われているプロトコルを実装したアプリケーションで使われているので、そう呼ばれているそうです。

しかし今回は、ウェルノウンポート番号は管理者権限でしか使えないため、それ以降の番号を指定して通信を行いました。

Threadを使っているのは、チャットの読み書きは非同期的に行われることが求められるためです。


WebServerアプリ

このサイトを参考にして、JavaでWebサーバアプリを作りました → 試作品

どういったプログラムを作ったかというと、サーバーの役割をするプログラムで、ブラウザからそのサーバーにアクセスした時に、自前で作ったhtmlファイルなどを表示するものです。

htmlの他にも、cssやjavascript、画像も出力させることができるので、以下のサンプルをダウンロードして、ドキュメントルートを変更した上で試してみてください(ポート番号は8080番なので、「localhost:8080/sample.html」でアクセスできる)。

sample.htmlsample.csssample.js404.htmlcat.jpeg


このプログラムを作るにあたり、HTTPプロトコルについて理解しなければならなかったので、このサイトで理解を深めました。概要としては、ブラウザがWebサーバにリクエストを送って、それに対してhtmlの情報などをWebサーバがレスポンスしているという感じです。今回は、ブラウザの機能は任せれば良いので、サーバー側の「ブラウザからのリクエストを受け取る」、「ブラウザにレスポンスを返す」という機能を持たせたプログラムを作りました。

このプログラムでは、200(成功)と404(失敗)のレスポンスを返すようにしたのですが、telnetコマンドを叩いて返ってくるような情報を自分で設定しなければなりませんでした。

またWebサーバなので、一度返して終わりではなく、何度もレスポンスしなればならないため、for文を使ってSocket.accept()を無限ループに入れています。

新しい考え方としてドキュメントルートも学びましたが、セキュリティ上の観点から、単純な割に強力なものであると思いました。


チャットアプリとWebサーバアプリは、基礎のところで使っている技術はほとんど共通していて、ネットワークプログラミングの基盤となる概念を学べたと思うので、いい勉強になったと思います。