教育サーバーのページ
オンラインテキスト目次
システムプログラミング演習

HTTP (HyperText Transfer Protocol)

HTTPは、Webサーバとブラウザの間で、要求と応答の受け渡しをおこなうため の通信規約(プロトコル)、つまり、HyperTextのやりとりを実現する プロトコルである。HyperTextとは、文書と文書、文書とマルチメディア情報 (音声、画像など)を関連づけることができるコンテンツを意味する。

HTTPは、TCP/IPにおけるアプリケーション層に位置し、ブラウザからの一つの 要求に対して、Webサーバは一つの応答を返す。 HTTPは、以下のようなリクエストメッセージとレスポンスメッセージから構成 される。

リクエスト(要求)メッセージ

WebブラウザからWebサーバに対して、データを要求する時送るメッセージ である。

リクエスト(要求)メッセージの形式は、以下のようになる。

リクエストメソッド一覧は、以下のようになる。

リクエスト(要求)メッセージの例を以下に示す。 たとえば、http://www.hoge.ac.jp/index.htmlに対応するリクエスト(要求) メッセージは、

GET  /index.html  HTTP/1.1 
HOST: www.hoge.ac.jp
(空行)
となる。

レスポンス(応答)メッセージ

リクエストメッセージに対するWebサーバの応答メッセージである。 メッセージの形式は以下のようになる。

ステータスコードの例を以下に示す。

レスポンスメッセージの例を以下に示す。

 
HTTP/1.1  200  OK
Data: Mon, 21 Apr 2003 09:15:00 GMT
Server: Apache/1.3 26(Unix) PHP/4.22
Last-Modified: Fri, 04 Apr 2003 04:32:48 GMT 
Etag: “10028-7fbf-3e8d0af0”
Content-Length: 32703
Content-Type: text/html

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
<HTML>
<HEAD>
<TITLE> TUIS /Eeducation Domain</TITLE>
</HEAD>
………
<BODY>
………
</BODY>
</HTML>

telnetを使ってHTTPを理解しよう

HTTPを理解するために、他のコンピュータと通信をおこなうプロトコル であるtelnetを用いて、Webサーバにリクエストメッセージを送信し、 どのようなレスポンスメッセージが返送されるかを調べよう。

Windows NT/2000/XP/Vista/7では、telnetウィンドウは開けないので、 コマンドプロンプトを起動する。コマンドプロンプトにおいて、

 C:\> telnet ↓(Enterを示す)

と打ち込み、telnetを起動する。

ただし、Windows 7では、telnetはデフォルトでは無効化設定されている。 そこで、コントロールパネルにある「プログラムと機能」を開き、左側の メニューに「Windowsの機能の有効化または無効化」という項目があるので、 これをクリックすると、Windowsの機能の画面が現れるので、「Telnetクライアント」 を有効にする。

 Microsoft Telnet> set localecho ↓(Enterを示す)
 Microsoft Telnet> set codeset Shift JIS ↓(Enterを示す)(日本語のページ)
 Microsoft Telnet> open www.hoge.ac.jp 80 ↓(Enterを示す)

と打ち込み、ローカルエコーの設定、文字コードの設定、www.hoge.ac.jpへの 接続をそれぞれおこなう。英語のページの場合には、codesetの設定を以下の ようにおこなう。

 Microsoft Telnet> set codeset JIS Kanji↓(Enterを示す)(自己紹介と英語のページ)

その後、telnetのウィンドウにおいて、次のリクエストを送信する。

 GET /index.html HTTP/1.1  ↓(Enterを示す)
 HOST: www.hoge.ac.jp 80 ↓(Enterを示す)
 ↓(Enterを示す)

すると、Webサーバから以下のようなレスポンスメッセージが送信される。

 
HTTP/1.1  200  OK
Data: Mon, 21 Apr 2003 09:15:00 GMT
Server: Apache/1.3 26(Unix) PHP/4.22
Last-Modified: Fri, 04 Apr 2003 04:32:48 GMT 
Etag: “10028-7fbf-3e8d0af0”
Content-Length: 32703
Content-Type: text/html

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
<HTML>
<HEAD>
<TITLE> TUIS /Eeducation Domain</TITLE>
</HEAD>
………
<BODY>
………
</BODY>
</HTML>

問題-1

telnetを使って、学内WebサーバにあるHTMLファイル(翔風祭実行本部 のWebページ、硬式野球部のWebページ、サッカー部のWebページ、大学のWebページなど)を 取得してみよ。

ただし、報告ではヘッダ情報はそのままとし、ボディ部分については その最初と最後の行だけでよく、途中は不必要。

問題-2

telnetを使って、1年次の情報リテラシーの授業で作成した自己紹介の HTMLファイルを取得するにはどうすればよいか。実際に、取得してみよ。

問題-3

HTTP プロトコルにおいて、GET要求の他に、指定したURLに対するWebサーバの応答ヘッダだけを取得するHEAD要求がある。 GET要求のための書式で、 GETHEAD で置き換えたリクエストを送るだけである。

telnetを使って、Webサーバにあるファイルに関するサーバヘッダを取得してみ よ。具体的には、問題-1、問題-2 で試してみたURLに関するサーバヘッダを取得 してみよ。ここでは、情報システム学科のWebサーバを使うことにする。

HTTPによるレスポンスメッセージ取得プログラムを理解しよう

次のプログラム getHtml0.java は、指定したWebサーバのホスト名と取得したいHTMLファイルを引数で指定して、Webサーバからのレスポンスを標準出力に表示するプログラムである。

import java.net.*;
import java.io.*;

public class getHtml0 {

    private static final int HTTP_port = 80;

    public static void main (String args[]) {

        String host= args[0];
        String filepath = args[1];
        String line;

        PrintWriter networkOut = null; //(準備)ソケットへの書き出し
        BufferedReader networkIn = null; //(準備)ソケットから読み出し
        try{
            Socket http = new Socket(host, HTTP_port);
            networkIn = new BufferedReader(
               new InputStreamReader(http.getInputStream(), "Shift_JIS"));
            //   new InputStreamReader(http.getInputStream(), "EUC_JP"));
            networkOut = new PrintWriter(http.getOutputStream());

            System.out.println("Connected to HTTP server " + host + "......");
            networkOut.print("GET " + filepath + " HTTP/1.1\n");
            networkOut.print("HOST: " + host + "\n");
            networkOut.print("\r\n\r\n");
            networkOut.flush();
            while ((line = networkIn.readLine()) != null) {
                System.out.print(line + "\n");
            }
        } // end of try
        catch (IOException e) {
            System.out.println("IOエラー発生");
            System.err.println(e);
        }
        finally {
            try {
                if (networkIn != null)
                    networkIn.close();
                if (networkOut != null)
                    networkOut.close();
            }
            catch (IOException e) {}
        }
    } // end of main
}
たとえば、Webサーバが動いているホスト www.edu.tuis.ac.jp のドキュメントルートにあるテキストファイル index.html を取得するには次のように getHtml0.java を使う。
% java getHtml0 www.edu.tuis.ac.jp /index.html
プログラム getHtml0.java の説明
引数で指定されたWebサーバのホスト名 args[0] と目的のHTMLファイル名 args[1] は
        String host= args[0];
        String filepath = args[1];
によって、それぞれ文字列変数 hostfilepath に格納される。

ポート番号は

    private static final int HTTP_port = 80;
で定数化してあり、
            Socket http = new Socket(host, HTTP_port);
によって、ホスト名とポート番号(80番)を与えてTCPソケットを開いている。 さらに、
            networkIn = new BufferedReader(
                    new InputStreamReader(http.getInputStream()));
            networkOut = new PrintWriter(http.getOutputStream());
で、入出力ストリームの生成とソケットへの結びつけを行っている。 これで、HTTP通信の準備ができた。なお、ここでは、レスポンスメッセージの一部 であるHTML文章の文字コードをShift_JISで送信することを設定してWriterをオープン (インスタンスを生成)している。 これ以降では、上のHTTPプロトコルに従った文字列の送受信を行えばよい。

実際、次のように Webサーバに GET 要求のための文字列を送信する。

            networkOut.print("GET " + filepath + " HTTP/1.1\n");
            networkOut.print("HOST: " + host + "\n");
            networkOut.print("\r\n\r\n");
            networkOut.flush();
ここで networkOut.flush() では、出力ストリームをフラッシュして、確実に文字列を送信する。

後は while(true) ループ

            while ((line = networkIn.readLine()) != null) {
                System.out.print(line + "\n");
によって、入力ストリームから1行ずつ読み込んだ文字列 line を表示して改行している。 これで、指定したHTMLファイルを入手して、標準出力に表示することになる。

これらの操作の課程において何らかの例外の発生が予測されるために、全体を構文 try{...} catch(..) {...} の中に入れていることに注意する。 この場合には、 finally {....} 構文も併用している。

問題-4

上のプログラム getHtml0.java を学内WebサーバにあるHTMLファイルを取得するために使ってみよ。 幾つかのHTMLファイルについて試みてみよ。

ただし、報告ではヘッダ情報はそのままとし、ボディ部分についてはその最初と最後の行だけでよく、途中は不必要。

問題-5

上のプログラム getHtml0.java で、自分の書いたHTMLファイルを取得するにはどうすればよいか。

問題-6

HTTP プロトコルにおいて、GET要求の他に、指定したURLに対するWebサーバの応答ヘッダだけを取得するHEAD要求がある。 GET要求のための書式で、 GETHEAD で置き換えたリクエストを送るだけである。

指定したWebサーバにあるファイルに関するサーバヘッダを取得するプログラム getHead.java を書け。 このプログラムを使って、問題-4、問題-5 で試してみたURLに関するサーバヘッダを取得してみよ。

システムプログラミング演習


nagai