diff --git a/src/j3/Phttpd.java b/src/j3/Phttpd.java index 7ad5360..73f28de 100644 --- a/src/j3/Phttpd.java +++ b/src/j3/Phttpd.java @@ -31,8 +31,10 @@ boolean cont = true; if (args.length==0) //引数がない場合、以下のファイルを返すことにする - args = new String[] { "j3/index.html" }; + args = new String[] { "src/j3/index.html" }; //相対パスで指定。windowsの場合、user.dir=NWP +// args = new String[] { "j3/index.html" };//Linuxの場合、通常はcd NWP/src しているはず System.out.println("このサーバは"+args[0]+"を返します。"); + System.out.println(System.getProperty("user.dir")); try { // サーバ用ソケットの作成(ポート番号8000番) servsock = new ServerSocket(8000); diff --git a/src/j3/Thttpd.java b/src/j3/Thttpd.java new file mode 100644 index 0000000..8559ca6 --- /dev/null +++ b/src/j3/Thttpd.java @@ -0,0 +1,119 @@ +package j3; +// いんちきHTTPサーバThttpd.java スレッド対応版 + +// このプログラムはポート番号8000番で動作するサーバです +// 使い方: java j3.Thttpd ファイル名 +// WWWクライアントからの接続に対して、引数で指定したファイルを返します。 + +// ライブラリの利用 +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.ServerSocket; +import java.net.Socket; + +// Thttpdクラス +public class Thttpd { + public static void main(String args[]) { + // サーバソケット + ServerSocket servsock = null; + Socket sock; + + // その他 + + if (args.length == 0) // 引数がない場合、以下のファイルを返すことにする + args = new String[] { "src/j3/index.html" }; //相対パスで指定。windowsの場合、user.dir=NWP + // args = new String[] { "j3/index.html" };//Linuxの場合、通常はcd NWP/src しているはず + System.out.println("このサーバは" + args[0] + "を返します。"); + System.out.println(System.getProperty("user.dir")); + try { + // サーバ用ソケットの作成(ポート番号8000番) + servsock = new ServerSocket(8000); + while (true) { + sock = servsock.accept();// 接続要求の受付 + new RequestHandler(sock, args[0]); + } + } catch (IOException e) { + System.out.println("異常終了:ポート番号の重複の可能性あり"); + System.exit(1); // 異常終了は1 + } + } +} + + +class RequestHandler implements Runnable { + Socket sock; + Thread thread; + + // 入出力 + DataOutputStream dostr; + BufferedReader in; + FileInputStream infile = null; + byte[] buff = new byte[1024]; + String file; + + RequestHandler(Socket s, String file) { + sock = s; + this.file = file; + thread = new Thread(this); + thread.start(); + } + + public void run(){ + try { + process(); + } catch (IOException e) { + e.printStackTrace(); + } + thread = null; + } + void process() throws IOException { + System.out.println("---\nConnection Requst from: " + (sock.getInetAddress())); + // 読み書き用オブジェクトの生成 + in = new BufferedReader(new InputStreamReader(sock.getInputStream())); + dostr = new DataOutputStream(sock.getOutputStream()); + // read headers + StringBuffer request = new StringBuffer(); + String line; + while ((line = in.readLine()) != null) { + System.out.println(line); + request.append(line + "\r\n"); + if (line.length() < 1) + break; + } + + // Response Headerの出力 + String CRLF = "\r\n"; + String response = "HTTP/1.1 200" + CRLF + "Content-type: text/html; charset=UTF-8" + CRLF + CRLF; + // オブジェクトinfileを作り,ファイルを準備します + try { + infile = new FileInputStream(file); + } catch (Exception e) { + // ファイル準備の失敗 + System.err.println("ファイルがありません"); + System.exit(1); + } + dostr.write(response.getBytes()); + + // Response Bodyの出力 + boolean cont = true; + while (cont) { + // ファイルからの読み込みとネットワーク出力 + try { + int n = infile.read(buff); + dostr.write(buff, 0, n); + } catch (Exception e) { // end of file + cont = false; + } + } + // おまけ:レスポンスヘッダを表示 + dostr.write(request.toString().getBytes()); + + // 接続終了 + sock.close(); + infile.close(); + } +} +