本系列教程將和您壹起探討如何利用Java語言壹步壹步實現自己的web服務器。
1需求描述
第1講我們要實現的效果是:當我們在瀏覽器的地址欄輸入localhost:8080的時候,我們會看到"hello,this is my web server!"。如下:
2實現
做任何事情都不能太急,對於編程來說也不例外。以上的案例雖然簡單,但卻是我們編寫web服務器的非常關鍵的壹步,麻雀雖小,五臟俱全。
2.1基礎知識
首先我們來分析壹下,為了實現上面的功能,我們需要具備哪些基礎知識。
1)CS架構介紹
CS架構是壹種非常常見的軟件架構,主要由兩部分組成:客戶端和服務器端即C端和S端。
圖2-1 CS架構
其壹般的交互流程為:客戶端發送壹條請求給服務器,服務器在收到請求後,解析處理該請求,並將結果以響應的方式返回給客戶端。
那麽在我們要要實現的需求中,客戶端特定為瀏覽器,請求特指Connection: keep-alivePragma: no-cacheCache-Control: no-cacheUpgrade-Insecure-Requests:1User-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.36Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8Accept-Encoding: gzip, deflate,sdchAccept-Language:zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4,ja;q=0.2
http響應報文:
HTTP/1.1200 OKCache-Control: privateContent-Length:21005Content-Type: text/htmlServer: Microsoft-IIS/7.0X-Powered-By: ASP.NETDate: Tue,07 Mar 201701: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.1200OK\\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)。。。
如想了解更多,歡迎關註“算法與編程之美”公眾號將持續為您帶來更多精彩內容。