Java例項開發05-02 簡單的HTTP伺服器端

weixin_33816946發表於2011-09-21

1.知識點:

  • 使用Java實現簡單的HTTP伺服器端
  • ServerSocket類和Socket類的使用
  • StringTokenizer類的使用
  • 多執行緒Thread

2.原始碼:

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.StringTokenizer;

public class httpServer {
  public static void main(String args[]) {
    int port = 9090;
    ServerSocket server_socket;
    try {
      // 監聽伺服器埠,等待連線請求
      server_socket = new ServerSocket(port);
      System.out.println("httpServer running on port " + server_socket.getLocalPort());
      // 顯示啟動資訊
      while (true) {
        Socket socket = server_socket.accept();
        System.out.println("New connection accepted " + socket.getInetAddress() + ":" + socket.getPort());
        // 建立分執行緒
        try {
          httpRequestHandler request = new httpRequestHandler(socket);
          Thread thread = new Thread(request);
          // 啟動執行緒
          thread.start();
        } catch (Exception e) {
          System.out.println(e);
        }
      }
    } catch (IOException e) {
      System.out.println(e);
    }
  }
}

class httpRequestHandler implements Runnable {
  final static String CRLF = "\r\n";
  Socket socket;
  InputStream input;
  OutputStream output;
  BufferedReader br;

  // 構造方法
  public httpRequestHandler(Socket socket) throws Exception {
    this.socket = socket;
    this.input = socket.getInputStream();
    this.output = socket.getOutputStream();
    this.br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
  }

  // 實現Runnable 介面的run()方法
  public void run() {
    try {
      processRequest();
    } catch (Exception e) {
      System.out.println(e);
    }
  }

  private void processRequest() throws Exception {
    while (true) {
      // 讀取並顯示Web 瀏覽器提交的請求資訊
      String headerLine = br.readLine();
      System.out.println("The client request is " + headerLine);
      if (headerLine.equals(CRLF) || headerLine.equals(""))
        break;
      StringTokenizer s = new StringTokenizer(headerLine);
      String temp = s.nextToken();
      if (temp.equals("GET")) {
        String fileName = s.nextToken();
        fileName = "." + fileName;
        // 開啟所請求的檔案
        FileInputStream fis = null;
        boolean fileExists = true;
        try {
          fis = new FileInputStream(fileName);
        } catch (FileNotFoundException e) {
          fileExists = false;
        }
        // 完成迴應訊息
        String serverLine = "Server: a simple java httpServer";
        String statusLine = null;
        String contentTypeLine = null;
        String entityBody = null;
        String contentLengthLine = "error";
        if (fileExists) {
          statusLine = "HTTP/1.0 200 OK" + CRLF;
          contentTypeLine = "Content-type: " + contentType(fileName) + CRLF;
          contentLengthLine = "Content-Length: " + (new Integer(fis.available())).toString() + CRLF;
        } else {
          statusLine = "HTTP/1.0 404 Not Found" + CRLF;
          contentTypeLine = "text/html";
          entityBody = "<HTML>" + "<HEAD><TITLE>404 Not Found</TITLE></HEAD>" + "<BODY>404 Not Found" + "<br>usage:http://yourHostName:port/"
              + "fileName.html</BODY></HTML>";
        }
        // 傳送到伺服器資訊
        output.write(statusLine.getBytes());
        output.write(serverLine.getBytes());
        output.write(contentTypeLine.getBytes());
        output.write(contentLengthLine.getBytes());
        output.write(CRLF.getBytes());
        // 傳送資訊內容
        if (fileExists) {
          sendBytes(fis, output);
          fis.close();
        } else {
          output.write(entityBody.getBytes());
        }
      }
    }
    // 關閉套接字和流
    try {
      output.close();
      br.close();
      socket.close();
    } catch (Exception e) {
    }
  }

  private static void sendBytes(FileInputStream fis, OutputStream os) throws Exception {
    // 建立一個 1K buffer
    byte[] buffer = new byte[1024];
    int bytes = 0;
    // 將檔案輸出到套接字輸出流中
    while ((bytes = fis.read(buffer)) != -1) {
      os.write(buffer, 0, bytes);
    }
  }

  private static String contentType(String fileName) {
    if (fileName.endsWith(".htm") || fileName.endsWith(".html")) {
      return "text/html";
    }
    return "fileName";
  }
}

 

目錄結構:專案根目錄下放一個HTML檔案

201109212127341539.png

 

3.測試結果:
執行程式,伺服器啟動了,然後開啟瀏覽器,輸入地址:

http://localhost:9090/1.html

201109212127503476.png

http://localhost:9090/2.html

201109212128145917.png

控制檯輸出:

201109212128223107.png

 





相關文章