Java多線程 Web服務器簡單實現

openkk 12年前發布 | 34K 次閱讀 Java Java開發

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URLDecoder;
import java.util.StringTokenizer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**

ServerSocket serverSocket;// 服務器Socket ExecutorService pool = Executors.newFixedThreadPool(2);

/**

  • 服務器監聽端口, 默認為 80. */ public static int PORT = 80;// 標準HTTP端口

/**

  • 開始服務器 Socket 線程. */ public SimpleHttpServer() { try { serverSocket = new ServerSocket(PORT); } catch (Exception e) { System.out.println("無法啟動HTTP服務器:" + e.getMessage()); } if (serverSocket == null) System.exit(1);// 無法開始服務器

// new Thread(this).start(); System.out.println("HTTP服務器正在運行,端口:" + PORT); while (true) { pool.execute(new Process(serverSocket)); } }

/**

  • 運行服務器主線程, 監聽客戶端請求并返回響應. */

/ */ /

  • 啟動 HTTP 服務器
  • @param args */ public static void main(String[] args) { try { if (args.length != 1) { System.out.println("這是一個簡單的web服務器 ,端口是: 80."); } else if (args.length == 1) { PORT = Integer.parseInt(args[0]); } } catch (Exception ex) { System.err.println("服務器初始化錯誤" + ex.getMessage()); }

new SimpleHttpServer(); } }

class Process extends Thread { private ServerSocket serverSocket;// 服務器Socket

Process(ServerSocket serverSocket) { this.serverSocket = serverSocket; }

public void run() { try { Socket client = null;// 客戶Socket client = serverSocket.accept();// 客戶機(這里是 IE 等瀏覽器)已經連接到當前服務器 if (client != null) { System.out.println("連接到服務器的用戶:" + client); try { // 第一階段: 打開輸入流 BufferedReader in = new BufferedReader( new InputStreamReader(client.getInputStream()));

System.out.println("客戶端發送的請求信息: ***"); // 讀取第一行, 請求地址 System.out.println("http協議頭部信息:"); String line = in.readLine(); System.out.println(line); String resource = line.substring(line.indexOf('/'), line.lastIndexOf('/') - 5); // 獲得請求的資源的地址 resource = URLDecoder.decode(resource, "gbk");// 反編碼

String method = new StringTokenizer(line).nextElement() .toString();// 獲取請求方法, GET 或者 POST

// 讀取瀏覽器發送過來的請求參數頭部信息 while ((line = in.readLine()) != null) { System.out.println(line);

if (line.equals("")) break; }

System.out.println("http協議頭部結束 ***"); System.out.println("用戶請求的資源是:" + resource); System.out.println("請求的類型是: " + method);

String params = null;

if (resource.indexOf("?") > -1) { params = resource.substring(resource.indexOf("?") + 1); resource = resource.substring(0, resource.indexOf("?")); }

// 顯示 POST 表單提交的內容, 這個內容位于請求的主體部分 if ("POST".equalsIgnoreCase(method)) { if (params != null) { params += "&" + in.readLine(); } else { params = in.readLine(); } }

System.out.println("打印提交的數據:"); printParams(params);

// 讀取資源并返回給客戶端 fileReaderAndReturn(resource, client); // 關閉客戶端鏈接 client.close(); System.out.println("客戶端返回完成!"); } catch (Exception e) { System.out.println("HTTP服務器錯誤:" + e.getMessage()); } }

} catch (Exception e) { System.out.println("HTTP服務器錯誤:" + e.getMessage()); } }

/**

  • 讀取一個文件的內容并返回給瀏覽器端.
  • @param fileName
  • 文件名
  • @param socket
  • 客戶端 socket.
  • @throws IOException */ void fileReaderAndReturn(String fileName, Socket socket) throws IOException { if ("/".equals(fileName)) {// 設置歡迎頁面,呵呵! fileName = "/index.html"; } fileName = fileName.substring(1);

PrintStream out = new PrintStream(socket.getOutputStream(), true); File fileToSend = new File(fileName);

String fileEx = fileName.substring(fileName.indexOf(".") + 1); String contentType = null; // 設置返回的內容類型 // 此處的類型與tomcat/conf/web.xml中配置的mime-mapping類型是一致的。測試之用,就寫這么幾個。 if ("htmlhtmxml".indexOf(fileEx) > -1) { contentType = "text/html;charset=GBK"; } else if ("jpegjpggifbpmpng".indexOf(fileEx) > -1) { contentType = "application/binary"; }

if (fileToSend.exists() && !fileToSend.isDirectory()) { // http 協議返回頭 out.println("HTTP/1.0 200 OK");// 返回應答消息,并結束應答 out.println("Content-Type:" + contentType); out.println("Content-Length:" + fileToSend.length());// 返回內容字節數 out.println();// 根據 HTTP 協議, 空行將結束頭信息

FileInputStream fis = null; try { fis = new FileInputStream(fileToSend); } catch (FileNotFoundException e) { out.println("<h1>404錯誤!</h1>" + e.getMessage()); } byte data[]; try { data = new byte[fis.available()];

fis.read(data); out.write(data); } catch (IOException e) { out.println("<h1>500錯誤!</h1>" + e.getMessage()); e.printStackTrace(); } finally { out.close(); try { fis.close(); } catch (IOException e) {

e.printStackTrace(); } } } else { out.println("<h1>404錯誤!</h1>" + "文件沒有找到"); out.close();

}

}

void printParams(String params) throws IOException { if (params == null) { return; } String[] maps = params.split("&"); for (String temp : maps) { String[] map = temp.split("="); System.out.println(map[0] + "==" + map[1]); } }

} </pre>

 本文由用戶 openkk 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!