網絡編程原理
一、DNS:
構成互聯網 Internet 的最基本的網絡協議就是互聯網協議 InternetProtocol,簡稱 IP 協議
。IP 地址就是互聯網的地址標識。
那麼手機上的App如何知道數據中心服務器的IP地址呢?開發工程師可以在App裏將這個IP地址固定寫,但是這樣做會帶來很多問題,比如會影響程序的可用性等。
事實上這個IP地址是通過DNS域名解析服務器得到的。當我們打開一個App的時候,App應用加載頁面的時候,這時候需要連接域名服務器進行域名解析,將 www.taobao.com 這樣的一個域名解析爲一個IP地址,然後連接目標服務器。
二、CDN:
CDN 是內容分發網絡 Content Delivery Network 的縮寫
。
我們能夠用手機或電腦上網,是因爲運營服務商爲我們提供了互聯網接入服務,將我們的手機和電腦連接到互聯網上。
App請求的數據最先達到的是運營服務商的機房,然後運營服務商通過自己搭建的骨幹網絡和交換節點
,將我們請求數據的目的地址發往互聯網任何地方。
爲了提高用戶請求訪問的速度,也爲了降低數據中心的負載壓力,淘寶會在全國各地各個主要的運營服務商的接入機房中部署一些緩存服務器,緩存那些靜態的圖片、資源文件等,這些緩存服務器構成了淘寶的 CDN。
如果用戶請求的數據是靜態資源,這些資源的 URL 通常以 image.taobao.com 之類的二級域名進行標識,域名解析的時候就會解析爲淘寶 CDN 的 IP 地址,請求先被 CDN 處理,如果 CDN 中有需要的靜態文件,就直接返回,如果沒有,CDN 會將請求發送到淘寶的數據中心,CDN 從淘寶數據中心獲得靜態文件後,一方面緩存在自己的服務器上,一方面將數據返回給用戶的 App。
三、HTTP:
1.簡介:
HTTP協議即超文本傳輸協議(HyperText Transfer Protocol)服務器傳輸超文本到本地瀏覽器的傳送協議
。HTTP是一個基於TCP/IP通信協議來傳遞數據。
HTTP是一個簡單的請求-響應協議,它通常運行在TCP之上。它指定了客戶端可能發送給服務器什麼樣的消息以及得到什麼樣的響應。HTTP是一個應用層協議。
在 TCP 傳輸層協議層面,就是保證建立通信兩方的穩定通信連接,將一方的數據以 bit 流的方式源源不斷地發送到另一方,至於這些數據代表什麼意思,哪裏是兩次請求的分界點,TCP 協議統統不管,需要應用層面自己解決。而互聯網應用需要在全球範圍爲用戶提供服務,將全球的應用和全球的用戶聯繫在一起,需要一個統一的應用層協議,這個協議就是 HTTP 協議。
2.主要特點:
- 簡單快速:向服務器請求服務時,只需傳送請求方法和路徑。 HTTP協議簡單,使得HTTP服務器的程序規模小,因而通信速度很快。
- 靈活:HTTP允許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type加以標記。
- 無連接:無連接的含義是限制每次連接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答後,即斷開連接。採用這種方式可以節省傳輸時間。
- 無狀態:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。
3.URL:
HTTP使用統一資源標識符
(Uniform Resource Identifiers, URI)來傳輸數據和建立連接。
http://www.51easymaster.com:8080/course/index?courseID=1&userID=24618&page=1#name
-
協議部分:該URL的協議部分爲“http:”,這代表網頁使用的是HTTP協議。
在Internet中可以使用多種協議,如HTTP,HTTPS,FTP等等本例中使用的是HTTP協議。在"HTTP"後面的“//”爲分隔符;
-
域名部分:該URL的域名部分爲"www.51easymaster.com"。一個URL中,也可以使用IP地址作爲域名使用。
-
端口部分:跟在域名後面的是端口,域名和端口之間使用" : "作爲分隔符。
端口不是一個URL必須的部分,如果省略端口部分,將採用默認端口; 本栗子端口是8080
-
虛擬目錄部分:從域名後的第一個" / " 開始到最後一個" / "爲止,是虛擬目錄部分。
虛擬目錄也不是一個URL必須的部分。本例中的虛擬目錄是"/course/"
-
文件名部分:從域名後的最後一個" / " 開始到 " ? " 爲止,是文件名部分。
如果沒有" ? “,則是從域名後的最後一個” / "開始到“#”爲止,是文件部分;
如果沒有" ? “和” # “,那麼從域名後的最後一個” / " 開始到結束,都是文件名部分;
本栗子文件名是"index"。文件名部分也不是一個URL必須的部分;
-
錨部分:從" # "開始到最後,都是錨部分。
錨部分也不是一個URL必須的部分;
本栗子錨的部分是"name"
-
參數部分:從" ? “開始到” # "爲止之間的部分爲參數部分,又稱搜索部分、查詢部分。
本栗子的參數部分爲"courseID=1&userID=24618&page=1"。
參數可以允許有多個參數,參數與參數之間用" & " 作爲分隔符
4.Request請求:
客戶端發送一個HTTP請求到服務器的請求消息包括以下格式:
- 請求行(request line);
- 請求頭部(header);
- 空行;
- 請求數據;
GET /image.jpg HTTP/1.1
Host img.taobao.com
User-Agent Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/32.36 (KHTML, like Gecko) Chrome/183.0.2704.106 Safari/32.36
Accept image/webp,image/*,*/*;q=0.8
Referer http://www.baidu.com/
Accept-Encoding gzip, deflate, sdch
Accept-Language zh-CN,zh;q=0.8
第一部分:請求行,用來說明請求類型,要訪問的資源以及所使用的HTTP版本。
GET:說明是GET請求類型;
/image.jpg:要訪問的資源,
HTTP /1.1 :版本號
第二部分:請求頭部,用來說明服務器要使用的附加信息。
Accept:瀏覽器可接受的MIME類型;
Accept - Charset:瀏覽器可接受的字符集;
Accept - Encoding:瀏覽器能夠進行解碼的數據編碼方式,比如gzip;
Accept - Language:瀏覽器所希望的語言種類,當服務器能夠提供一種以上的語言版本時要用到;
Authorization:授權信息,通常出現在對服務器發送的WWW - Authenticate頭的應答中;
Connection:表示是否需要持久連接;
Content - Length:表示請求消息正文的長度;
Cookie:當前頁面設置的任何Cookie;
Host:初始URL中的主機和端口;
Pragma:指定“no - cache”值表示服務器必須返回一個刷新後的文檔,即使它是代理服務器而且已經有了頁面的本地拷貝。
Referer:包含一個URL,用戶從該URL代表的頁面出發訪問當前請求的頁面;
User - Agent:瀏覽器類型,如果Servlet返回的內容與瀏覽器類型有關則該值非常有用;
UA - Pixels,UA - Color,UA - OS,UA - CPU:由某些版本的IE瀏覽器所發送的非標準的請求頭,表示屏幕大小、顏色深度、操作系統和CPU類型。
第三部分:空行
即使第四部分的請求數據爲空,也必須有空行;
第四部分:請求主體,可以添加任意其他數據;
此栗子請求主體爲空;
請求方法主要有:GET、POST、HEAD、PUT、DELETE、CONNECT、OPTIONS、TRACE。
- GET:請求指定的頁面信息,並返回實體主體;
- POST:向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中,POST請求可能會導致新的資源的建立和/或已有資源的修改;
- HEAD:類似於get請求,只不過返回的響應中沒有具體的內容,用於獲取報頭;
- PUT:從客戶端向服務器傳送的數據取代指定的文檔的內容;
- DELETE:請求服務器刪除指定的頁面;
- CONNECT:HTTP/1.1協議中預留給能夠將連接改爲管道方式的代理服務器;
- OPTIONS:允許客戶端查看服務器的性能;
- TRACE: 回顯服務器收到的請求,主要用於測試或診斷;
5.Response響應:
一般情況下,服務器接收並處理客戶端發過來的請求後會返回一個HTTP的響應消息。
HTTP響應也是由四個部分組成:
- 狀態行;
- 消息報頭;
- 空行;
- 響應正文;
HTTP/1.1 200 OK
Date: Fri, 26 May 2019 16:07:21 GMT
Content-Type: text/html; charset=UTF-8
<html>
<head></head>
<body>
<!--fe_cow-->
</body>
</html>
第一部分:狀態行,由HTTP協議版本號,狀態碼,狀態消息三部分組成;
HTTP/1.1 :協議版本號;
200:狀態碼;
OK:狀態消息"OK"
第二部分:消息報頭,用來說明客戶端要使用的一些附加信息
Date:生成響應的日期喝時間;
Content-Type: 指定 MIME類型的 HTML(text/html),編碼類型是UTF-8;
第三部分:空行
消息報頭後面的空行是必須有;
第四部分:響應正文,服務器返回給客戶端的文本信息
> < html>
> < head></head>
> < body>
> <!--fe_cow-->
> </body>
> </html>
響應狀態碼:
-
狀態碼是 200,表示響應正常。
-
響應狀態碼是 3XX,表示請求被重定向。
301:代表永久性轉移;
302:表示請求被臨時重定向到新的 URL,響應頭中包含新的臨時 URL,客戶端收到響應後,重新請求這個新的 URL;
-
狀態碼是 4XX,表示客戶端錯誤。
401:是沒有帶認證信息或者帶了錯誤的認證信息, 這時客戶端可以修改認證信息進行重試 ;
403:客戶端帶了正確的認證信息, 但服務器認爲這個認證信息對應的用戶是沒有對應資源的訪問權限的;
404:表示請求的頁面不存在;
-
狀態碼是 5XX,表示服務器異常。
500:請求未完成;
502:請求處理超時;
503:服務器過載;
如果響應正常,那麼在響應頭之後就是響應 body,瀏覽器的響應 body 通常是一個 HTML 頁面,App 的響應 body 通常是個 JSON 字符串。
6.HTTP工作原理:
以下是HTTP請求/響應的步驟:
-
客戶端連接Web服務器:
-
一個HTTP客戶端,通常是瀏覽器,與Web服務器的HTTP端口(默認爲80)建立一個TCP套接字連接。
比如 http:www.taobao.com
-
-
發送HTTP請求:
- 通過TCP套接字,客戶端向Web服務器發送一個文本的請求報文,一個請求報文由請求行、請求頭部、空行和請求數據4部分組成。
-
服務器接受請求並返回HTTP響應:
- Web服務器解析請求,定位請求資源。服務器將資源複本寫到TCP套接字,由客戶端讀取。一個響應由狀態行、響應頭部、空行和響應數據4部分組成。
-
釋放連接TCP連接:
- 若connection 模式爲close,則服務器主動關閉TCP連接,客戶端被動關閉連接,釋放TCP連接;若connection 模式爲keepalive,則該連接會保持一段時間,在該時間內可以繼續接收請求;
-
客戶端瀏覽器解析HTML內容:
- 客戶端瀏覽器首先解析狀態行,查看錶明請求是否成功的狀態代碼。
- 然後解析每一個響應頭,響應頭告知以下爲若干字節的HTML文檔和文檔的字符集。
- 客戶端瀏覽器讀取響應數據HTML,根據HTML的語法對其進行格式化,並在瀏覽器窗口中顯示。
瀏覽器地址欄輸入URL地址,按回車會經歷的以下流程:
- 瀏覽器向 DNS 服務器請求解析該 URL 中的域名所對應的 IP 地址;
- 解析出 IP 地址後,根據該 IP 地址和默認端口 80,和服務器建立TCP 連接;
- 瀏覽器發出讀取文件(URL 中域名後面部分對應的文件)的HTTP 請求,該請求報文作爲 TCP 三次握手 的第三個報文的數據發送給服務器;
- 服務器對瀏覽器請求作出響應,並把對應的 html 文本發送給瀏覽器;
- 釋放TCP連接;
- 瀏覽器將該 html 文本並顯示內容;
7.GET請求與POST請求的區別:
-
GET提交的數據會放在URL
之後,以?分割URL和傳輸數據,參數之間以&相連。POST方法
是把提交的數據放在HTTP包的Body中
。index?courseID=1&userID=24618&page=1
-
GET提交的
數據大小有限制
(因爲瀏覽器對URL的長度有限制),而POST方法提交的數據沒有限制
。 -
GET方式需要使用
Request.QueryString
來取得變量的值,而POST方式通過Request.Form
來獲取變量的值。 -
GET方式提交數據,會帶來
安全問題
。比如一個登錄頁面,通過GET方式提交數據時,用戶名和密碼將出現在URL上,如果頁面可以被緩存或者其他人可以訪問這臺機器,就可以從歷史記錄獲得該用戶的賬號和密碼;
四、TCP:
應用程序使用操作系統的 socket 接口進行網絡編程,socket 裏封裝了 TCP 協議
。應用程序通過 socket 接口使用 TCP 協議完成網絡編程,socket 或者 TCP 在應用程序看就是一個底層通信協議,事實上,TCP 僅僅是一個傳輸層協議
。
傳輸層協議 TCP 和網絡層協議 IP 共同構成 TCP/IP 協議棧,成爲互聯網應用開發最主要的通信協議。
OSI 開放系統互聯模型將網絡協議定義了 7 層,TCP/IP 協議棧將 OSI 頂部三層協議應用層、表示層、會話層合併爲一個應用層
,HTTP 協議就是 TCP/IP 協議棧中的應用層協議。
開放系統互連參考模型 (Open System Interconnect 簡稱OSI)是國際標準化組織(ISO)和國際電報電話諮詢委員會(CCITT)聯合制定的開放系統互連參考模型,爲開放式互連信息系統提供了一種功能結構的框架。
- 應用層:提供網絡與用戶應用軟件之間的接口服務;
- 表示層:提供格式化的表示和轉換數據服務,如加密和壓縮;
- 會話層:提供包括訪問驗證和會話管理在內的建立和維護應用之間通信的機制;
- 傳輸層:提供建立、維護和取消傳輸連接功能,負責可靠地傳輸數據,TCP連接;
- 網絡層:網絡層的數據需要交給鏈路層進行處理,而鏈路層幀的大小定義了最大傳輸單元,網絡層的 IP 數據包必須要小於最大傳輸單元才能進行網絡傳輸,這個數據包也有一個 IP 頭,主要包括的就是發送者和接受者的 IP 地址。
- 數據鏈路層:就是將數據進行封裝後交給物理層進行傳輸,主要就是將數據封裝成數據幀,以幀爲單位通過物理層進行通信,有了幀,就可以在幀上進行數據校驗,進行流量控制。數據鏈路層會定義幀的大小,這個大小也被稱爲最大傳輸單元。
- 物理層:負責數據的物理傳輸,計算機輸入輸出的只能是 0 1 這樣的二進制數據,但是在真正的通信線路里有光纖、電纜、無線各種設備。光信號和電信號,以及無線電磁信號在物理上是完全不同的,如何讓這些不同的設備能夠理解、處理相同的二進制數據,這就是物理層要解決的問題。
1.TCP 三次握手和四次揮手:
注意:專業述語
ack —— 確認號碼
seq —— 順序號碼
ISN —— 初始序列號
ACK —— 確認,使得確認號有效 (握手使用)
SYN —— 用於初始化一個連接的序列號,建立連接
Seq —— 表示請求建立連接
FIN —— 該報文的發送方已經結束向對方發送數據
三次握手,實際就是客戶端 和 服務器 建立穩定TCP 連接的 發送三個包的過程:
第一次握手:(SYN=1,Seq=X)
App 先發送 SYN=1,Seq=X 的報文,表示請求建立連接,X 是一個隨機數;
第二次握手:(SYN=1,ACK=X+1,Seq=Y)
服務器收到這個報文後,應答 SYN=1,ACK=X+1,Seq=Y 的報文,表示同意建立連接;
第三次握手:(ACK=Y+1,Seq=Z)
App 收到這個報文後,檢查 ACK 的值爲自己發送的 Seq 值 +1,確認建立連接,併發送 ACK=Y+1 的報文給服務器;服務器收到這個報文後檢查 ACK 值爲自己發送的 Seq 值 +1,確認建立連接。至此,App 和服務器建立起 TCP 連接,就可以進行數據傳輸了。
舉個形象的栗子,有A(客戶端) 和 B(服務器) 想進行通話:
- A 先對 B 說:“喂,你在麼?我在的,我的口令是 “x”。
- B 收到之後大聲回答:“我收到你的口令 “x” 並準備好了,你準備好了嗎?我的口令是 “y”。
- ”A 收到之後也大聲回答:“我收到你的口令 “y” 並準備好了,我們開始吧。
TCP建立一個連接需3次握手,而終止一個連接則需要四次揮手;
-
一方應用程序調用 close,我們稱該方爲
主動關閉方
,該端的 TCP 發送一個FIN 包
,表示需要關閉連接。之後主動關閉方進入 FIN_WAIT_1 狀態;
-
FIN 包的對端執行被動關閉。這個 FIN 由 TCP 協議棧處理。
我們知道,TCP 協議棧爲 FIN 包插入一個文件結束符 EOF 到接收緩衝區中,應用程序可以通過 read 調用來感知這個 FIN 包;
這個 EOF 會被放在已排隊等候的其他已接收的數據之後,這就意味着接收端應用程序需要處理這種異常情況,因爲 EOF 表示在該連接上再無額外數據到達;
被動關閉方進入 CLOSE_WAIT 狀態;
-
接下來,被動關閉方將讀到這個 EOF,應用程序也調用 close 關閉它的套接字,這導致它的 TCP 也發送一個 FIN 包。
被動關閉方將進入 LAST_ACK 狀態;
-
主動關閉方接收到對方的 FIN 包,並確認這個 FIN 包。
主動關閉方進入 TIME_WAIT 狀態,而接收到 ACK 的被動關閉方則進入 CLOSED 狀態。進過 2MSL 時間之後,主動關閉方也進入 CLOSED 狀態;
每個方向都需要一個FIN 和 一個ACK ,因此通常被稱爲 四次揮手;
五、一個字符的發送處理:
如果我們以POST方法提交一個搜索請求給淘寶服務器,那麼最終在數據鏈路層構建出來的數據幀大概是這樣的。
- APP 要發送的數據只是 key = “a”,這樣一個JSON 字符串,每一層協議都會在上一層協議基礎上添加一個頭部信息,最後封裝成一個鏈路層的數據幀在網絡上傳輸,發送給淘寶服務器。
- 淘寶的服務器在收到這個數據幀後,在通信協議的每一層進行校驗檢查,確保數據準確後,將頭部信息刪除,再交給自己的上一層協議處理。
- HTTP 應用服務器在最上層,負責 HTTP 協議的處理,最後將 key=“a”這個 JSON 字符串交給淘寶工程師開發的應用程序處理。
參考資料:
《後端技術基礎38講》
《網絡編程實戰》