1. 程式人生 > >B/S結構,服務器端的結構分析與部分實現

B/S結構,服務器端的結構分析與部分實現

生成 因此 puts kit 服務器 請求 cati 集成 servers

1.1 簡述

瀏覽器在訪問一個IP地址的時候,一般會自動在地址前方加上HTTP:// 表示其基於http協議訪問。

一般而言,http跟tcp在本質上沒有區別。

tcp連接的過程,在JAVA語言中,在java.net包中被集成,可以很方便的調用。

Socket s = new Socket("IP地址",端口號);

技術分享圖片

tcp連接的確立基於三次握手,其過程本質上是C端與S端相互驗證,建立信任的一種方式。http跟tcp在網絡通信中所屬的層級不同,但http協議大致是在tcp基礎上,需要額外一些相互驗證,建立信任的方式,以滿足http協議的需要。如同tcp協議鏈接過程的三次握手一般,http也有一套固定的驗證格式。

因此,使用Socket類,在此基礎之上將其固定的驗證格式實現,將C端請求的內容以一定格式解析,將響應內容以一定格式包裝,便可以實現響應http請求。

1.2 大致的結構

技術分享圖片

如圖,一個HTTP請求與響應的流程大致如此

1、瀏覽器端向服務器發送一個http請求,其數據由服務器端一個基於Socket協議的接收器接收。

2、接收器將接收到的數據交由一內容解析器解析,以獲取該http請求的請求內容。

3、解析器將解析出來的內容交由業務處理器,業務處理器負責根據請求生成響應的內容,其可以是一個html頁面,可以是一張圖片,也可以是一段代碼塊,之後將內容交由包裝器。

4、包裝器將內容包裝成http響應的相應格式。

5、基於Socket協議的發送器將包裝好的內容發送給瀏覽器。

其中瀏覽器的部分自然不需要我們實現,而Socket的部分直接使用java.net中現成的東西,構建一個能響應http請求的服務器,所需要實現的是:

1、HTTP請求內容解析器

2、HTTP響應內容包裝器

3、業務處理部分。

1.3 HTTP請求內容解析器

創建一個Socket

ServerSocket ss = new ServerSocket(8888);
		Socket s = ss.accept();
		BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
		String str = null;
		while ((str = br.readLine()) != null) {
			System.out.println(str);
		}
		br.close();
		s.close();
		ss.close();

  使用本地瀏覽器訪問一次,便可獲得http響應中包含的內容:

GET / HTTP/1.1
Host: localhost:8888
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9

其中包含的內容有訪問的方式,HTTP協議的版本,可以返回的數據格式,瀏覽器的信息等。

先考慮GET方式,一般而言,http的C端,其期望執行的業務,以參數的形式,通過HTTP協議內容進行傳遞。

在訪問地址後面加上請求的業務參數和其他社麽東西。

技術分享圖片

GET /login.html?username=gaga HTTP/1.1
Host: localhost:8888
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9

 發現URL中的Path部分被完整的添加到了http請求中的第一行。

也就是說,如果業務參數僅包含URL中的內容(不考慮不同的瀏覽器或者啥),HTTP請求內容解析器所需要解析的東西,僅包括http請求中的第一行。

1.4 HTTP響應內容包裝器

http響應格式必須遵循http響應的格式,其包括響應體和響應頭兩部分,中間以一個換行符分隔。

其中響應頭的第一行必須遵循HTTP版本+響應狀態+響應狀態描述的格式組成。其他就沒什麽要求了。

技術分享圖片

技術分享圖片

最簡單的一響應格式比如

PrintStream ps = new PrintStream(s.getOutputStream());
		ps.println("HTTP/1.1 200 OK");
		ps.println();
		ps.write("你好".getBytes());

  其執行的結果:

技術分享圖片

B/S結構,服務器端的結構分析與部分實現