50行程式碼實現簡單的網站伺服器 (一)
歡迎點選「演算法與程式設計之美」↑關注我們!
本文首發於微信公眾號:"演算法與程式設計之美",歡迎關注,及時瞭解更多此係列部落格。
本系列教程將和您一起探討如何利用Java語言一步一步實現自己的web伺服器。
1 需求描述
第1講我們要實現的效果是:當我們在瀏覽器的位址列輸入localhost:8080的時候,我們會看到"hello,this is my web server!"。如下:
2 實現
做任何事情都不能太急,對於程式設計來說也不例外。以上的案例雖然簡單,但卻是我們編寫web伺服器的非常關鍵的一步,麻雀雖小,五臟俱全。
2.1 基礎知識
首先我們來分析一下,為了實現上面的功能,我們需要具備哪些基礎知識。
1) CS架構介紹
CS架構是一種非常常見的軟體架構,主要由兩部分組成:客戶端和伺服器端即C端和S端。
圖 2-1 CS架構
其一般的互動流程為:客戶端傳送一條請求給伺服器,伺服器在收到請求後,解析處理該請求,並將結果以響應的方式返回給客戶端。
那麼在我們要要實現的需求中,客戶端特定為瀏覽器,請求特指http請求,響應特指http響應。
一般情況CS架構的軟體,我們需要分別開發C端和S端的程式,但是由於本題客戶端就是我們日常使用的瀏覽器,所以我們不需要開發C端程式,所以僅需要開發伺服器端程式。
這是我們實現需求需要了解的第一個基礎知識。
2)http請求和響應
有了上面的基礎知識後,接下來我們需要具體的瞭解,這個
下面我們來看一個具體的請求和響應報文的格式:
http請求報文:
GET / HTTP/1.1 Host: www.sctu.edu.cn Connection: keep-alive Pragma: no-cache Cache-Control: no-cache Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0(Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko)Chrome/56.0.2924.87 Safari/537.36 Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Encoding: gzip, deflate,sdch Accept-Language:zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4,ja;q=0.2
http響應報文:
HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 21005
Content-Type: text/html
Server: Microsoft-IIS/7.0
X-Powered-By: ASP.NET
Date: Tue, 07 Mar 2017 01:59:58GMT
如想了解更多,演算法與程式設計之美公眾號的《BS架構基礎 -http報文》有簡單易懂的介紹。
3)Socket程式設計
有了以上的基礎知識之後,我們還需要了解Java在實現CS架構時使用的具體技術,那就是socket程式設計。socket程式設計的入門其實並不難,下面為大家做簡要介紹:
- socket程式設計可以分為兩部分,一部分為伺服器端的程式設計,另外一部分為客戶端。對於伺服器端我們使用ServerSocket類,客戶端使用Socket類。
- 一旦建立連線後,獲取了客戶端的socket物件,接下來就可以通過socket物件的InputStream來讀取請求,而OutputStream來寫響應。
只需要瞭解上面的兩點即可,如想了解更多,演算法與程式設計之美公眾號的《Socket程式設計基礎》有簡單易懂的介紹。
2.2 實現
有了上面的3個基礎知識點後,接下來我們可以開始程式設計實現了。
主要的業務流程為:
1. 伺服器端利用ServerSocket開啟8080埠開始監聽;
2. 當有客戶端發起的http請求時,接受該客戶端讀取http請求,進行相關處理;
3. 返回http響應。
具體的程式碼實現如下:
public class WebServer {
private ServerSocket serverSocket;
public WebServer() {
try {
// 開啟8080埠監聽
serverSocket = newServerSocket(8080);
} catch (IOException e) {
e.printStackTrace();
}
}
public void run(){
try {
Socket socket =serverSocket.accept();
// 讀取http請求
BufferedReader reader = newBufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
while (!(line =reader.readLine()).equals("")) {
System.out.println(line);
}
// 返回http響應
PrintWriter writer = newPrintWriter(socket.getOutputStream());
writer.print("HTTP/1.1 200OK\r\n");
writer.print("\r\n");
writer.print("hello, thisis my web server!");
writer.flush();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new WebServer().run();
}
}
3 總結
我們已經按照需求實現了相關功能,但是細心的你可能會發現以下的問題:
1)瀏覽器重新整理一次,伺服器端程式就終止了;
2)這個伺服器能不能作為靜態網頁html伺服器呢?
3)。。。
如想了解更多,歡迎關注“演算法與程式設計之美”公眾號將持續為您帶來更多精彩內容。有任何疑問歡迎留言。