手寫一個最迷你的Web伺服器
相信大家對Tomcat伺服器應該都很熟悉了,我們幾乎每天都會用它,它的安裝目錄結構大致如下:
今天我們就仿照Tomcat伺服器來手寫一個最簡單最迷你版的web伺服器,僅供學習交流。
1. 在你windows系統盤的F盤下,建立一個資料夾webroot,用來存放前端程式碼。
2. 建立一個簡單的Java專案,專案結構如下圖:
3. 程式碼介紹:
(1)ServerThread.java 核心程式碼,主要用於web檔案的讀取與解析等。程式碼如下:
package server; import java.io.*; import java.net.Socket; import java.util.Date; import java.util.HashMap; import java.util.Map; /** * @ClassName: ServerThread * @Description: * @Author: liuhefei * @Date: 2019/6/23 * @blog: **/ public class ServerThread implements Runnable { private static Map<String, String> contentMap = new HashMap<>(); //可以參照Tomcat的web.xml配置檔案 static { contentMap.put("html", "text/html"); contentMap.put("htm", "text/html"); contentMap.put("jpg", "image/jpeg"); contentMap.put("jpeg", "image/jpeg"); contentMap.put("gif", "image/gif"); contentMap.put("js", "application/javascript"); contentMap.put("css", "text/css"); contentMap.put("json", "application/json"); contentMap.put("mp3", "audio/mpeg"); contentMap.put("mp4", "video/mp4"); } private Socket client; private InputStream in; private OutputStream out; private PrintWriter pw; private BufferedReader br; private static final String webroot = "F:\webroot\"; //此處目錄,你可以自行修改 public ServerThread(Socket client){ this.client = client; init(); } private void init(){ //獲取輸入輸出流 try { in = client.getInputStream(); out = client.getOutputStream(); } catch (IOException e) { e.printStackTrace(); } } @Override public void run() { try { gorun(); } catch (Exception e) { e.printStackTrace(); } } private void gorun() throws Exception { //讀取請求內容 BufferedReader reader = new BufferedReader(new InputStreamReader(in)); String line = reader.readLine().split(" ")[1].replace("/", "\"); //請求的資源 if(line.equals("\")){ line += "index.html"; } System.out.println(line); String strType = line.substring(line.lastIndexOf(".")+1, line.length()); //獲取檔案的字尾名 System.out.println("strType = " + strType); //給使用者響應 PrintWriter pw = new PrintWriter(out); InputStream input = new FileInputStream(webroot + line); //BufferedReader buffer = new BufferedReader(new InputStreamReader(input)); pw.println("HTTP/1.1 200 ok"); pw.println("Content-Type: "+ contentMap.get(strType) +";charset=utf-8"); pw.println("Content-Length: " + input.available()); pw.println("Server: hello"); pw.println("Date: " + new Date()); pw.println(); pw.flush(); byte[] bytes = new byte[1024]; int len = 0; while ((len = input.read(bytes)) != -1){ out.write(bytes, 0, len); } pw.flush(); input.close(); pw.close(); reader.close(); out.close(); client.close(); } }
(2)HttpServer.java (普通版)服務端
package server; import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.util.Date; /** * @ClassName: HttpServer * @Description: 服務端 * @Author: liuhefei * @Date: 2019/6/23 * @blog: **/ public class HttpServer { public static void main(String[] args) throws IOException { //啟動伺服器,監聽9005埠 ServerSocket server = new ServerSocket(9005); System.out.println("伺服器啟動,監聽9005埠...."); while (!Thread.interrupted()){ //不停接收客戶端請求 Socket client = server.accept(); //開啟執行緒 new Thread(new ServerThread(client)).start(); } server.close(); } }
(2)HttpServer1.java (執行緒池版)服務端
package server; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * @ClassName: HttpServer * @Description: 服務端 * @Author: liuhefei * @Date: 2019/6/23 * @blog: **/ public class HttpServer1 { public static void main(String[] args) throws IOException { //建立執行緒池 ExecutorService pool = Executors.newCachedThreadPool(); //啟動伺服器,監聽9005埠 ServerSocket server = new ServerSocket(9005); System.out.println("伺服器啟動,監聽9005埠...."); while (!Thread.interrupted()){ //不停接收客戶端請求 Socket client = server.accept(); //向執行緒池中提交任務 pool.execute(new ServerThread(client)); } server.close(); pool.shutdown(); } }
4. 將一個具有index.html的靜態頁面檔案拷入到我們建立的webroot目錄下。相關的靜態web資原始碼可以到原始碼之家下載或是自己編寫。
5. 啟動web服務,啟動HttpServer.java 或HttpServer1.java都可以,服務啟動之後將會監聽9005埠。
6. 我們到瀏覽器上訪問我們的服務,訪問地址:
即可看到效果,我的效果如下:
控制檯列印如下:
到這裡,一個簡單的Web伺服器就完成了。
程式碼見:
僅供參考學習,感謝諸君的支援!
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3016/viewspace-2823243/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 手寫一個迷你版 HashMap,面試隨便問!HashMap面試
- 手寫迷你Spring框架Spring框架
- 一起寫一個 Web 伺服器Web伺服器
- 自己寫一個Web伺服器(1)Web伺服器
- 自己寫一個Web伺服器(2)Web伺服器
- 自己寫一個Web伺服器(3)Web伺服器
- 一起寫一個 Web 伺服器(1)Web伺服器
- 一起寫一個 Web 伺服器(2)Web伺服器
- 一起寫一個Web伺服器(3)Web伺服器
- 手寫一個靜態伺服器伺服器
- 用一個檔案,實現迷你 Web 框架Web框架
- 自己動手開發一個 Web 伺服器(一)Web伺服器
- 自己動手開發一個 Web 伺服器(三)Web伺服器
- 自己動手開發一個 Web 伺服器(二)Web伺服器
- 自己動手做一個迷你 Linux 系統(轉)Linux
- 手寫啟動一個本地伺服器的命令列工具伺服器命令列
- 最簡單的web伺服器實現(一)Web伺服器
- 使用Node.js原生API寫一個web伺服器Node.jsAPIWeb伺服器
- 一個最簡單的web componentsWeb
- 手寫一個自己的PromisePromise
- 手寫一個PromisePromise
- 手把手教你手寫一個最簡單的 Spring Boot StarterSpring Boot
- 寫一個最簡陋的node框架框架
- 開源而又強大的迷你型web伺服器推薦Web伺服器
- 手寫一個簡易的WebpackWeb
- 搭個 Web 伺服器(一)Web伺服器
- Apache Vs Nginx哪個最適合您的 Web 伺服器?ApacheNginxWeb伺服器
- 寫一個最簡陋的node框架(2)框架
- 手寫一個最簡單的IOC容器,從而瞭解spring的核心原理Spring
- 手寫一個超簡單的VueVue
- 純手寫web框架Web框架
- 實現一個迷你版的RPCRPC
- 手寫一個解析器
- 從頭手寫一個PromisePromise
- 手寫一個LRU工具類
- 手寫一個 React 動畫元件React動畫元件
- 手寫一個vue-routerVue
- 自己動手寫一個 SimpleVueVue