Newer
Older
my90NWP / src / j3 / Thttpd.java
@Motoki Miura Motoki Miura on 26 Oct 2021 3 KB add Thread httpd
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();
    }
}