1. 程式人生 > >50行程式碼實現簡單的網站伺服器 (一)

50行程式碼實現簡單的網站伺服器 (一)

歡迎點選「演算法與程式設計之美」↑關注我們!

本文首發於微信公眾號:"演算法與程式設計之美",歡迎關注,及時瞭解更多此係列部落格。


本系列教程將和您一起探討如何利用Java語言一步一步實現自己的web伺服器。

需求描述

1講我們要實現的效果是:當我們在瀏覽器的位址列輸入localhost:8080的時候,我們會看到"hello,this is my web server!"。如下:

實現

做任何事情都不能太急,對於程式設計來說也不例外。以上的案例雖然簡單,但卻是我們編寫web伺服器的非常關鍵的一步,麻雀雖小,五臟俱全。

2.1 基礎知識

首先我們來分析一下,為了實現上面的功能,我們需要具備哪些基礎知識。

1 CS架構介紹

CS架構是一種非常常見的軟體架構,主要由兩部分組成:客戶端和伺服器端即C端和S端。

 2-1 CS架構

其一般的互動流程為:客戶端傳送一條請求給伺服器,伺服器在收到請求後,解析處理該請求,並將結果以響應的方式返回給客戶端。

那麼在我們要要實現的需求中,客戶端特定為瀏覽器,請求特指http請求,響應特指http響應。

一般情況CS架構的軟體,我們需要分別開發C端和S端的程式,但是由於本題客戶端就是我們日常使用的瀏覽器,所以我們不需要開發C端程式,所以僅需要開發伺服器端程式。

這是我們實現需求需要了解的第一個基礎知識。

2http請求和響應

有了上面的基礎知識後,接下來我們需要具體的瞭解,這個

http請求長什麼樣,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報文》有簡單易懂的介紹。

3Socket程式設計

有了以上的基礎知識之後,我們還需要了解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();

   }

}

 總結

我們已經按照需求實現了相關功能,但是細心的你可能會發現以下的問題:

1)瀏覽器重新整理一次,伺服器端程式就終止了;

2)這個伺服器能不能作為靜態網頁html伺服器呢?

3)。。。

如想了解更多,歡迎關注“演算法與程式設計之美”公眾號將持續為您帶來更多精彩內容。有任何疑問歡迎留言。