OSI是Open System Interconnection的縮寫,意爲開放式系統互聯。國際標準化組織(ISO)制定了OSI模型,該模型定義了不一樣計算機互聯的標準,是設計和描述計算機網絡通訊的基本框架。OSI模型把網絡通訊的工做分爲7層,分別是物理層、數據鏈路層、網絡層、傳輸層、會話層、表示層和應用層。html
記憶方法:記住前面的第一個字程序員
物 數 網 傳 會 表 應
這七層每一層都有本身的做用,做用以下圖分解:web
HTTP(HyperText Transfer Protocol、超文本傳輸協議)是OSI七層中應用層的協議。編程
HTTP 是基於 TCP/IP協議的應用層協議。它不涉及數據包(packet)傳輸,主要規定了客戶端和服務器之間的通訊格式,默認使用80端口。
有人說HTTP是一個基於TCP/IP通訊協議來傳遞數據(HTML 文件, 圖片文件, 查詢結果等),我覺這句話有問題,HTTP要是定義爲協議那麼http只是一種規定規則,規定了客戶端的URI請求格式以及服務端數據響應格式,要說HTTP請求這個概念久比較籠統了,客戶端發送一次HTTP請求,通過OSI的七層協議的組裝、傳輸、拆分、傳輸等一些操做,最終能夠得到咱們想要的數據。瀏覽器
解決客戶端和服務端的數據如何包裝,包裝兩端最後獲得的數據能夠被識別。
TPC/IP協議是傳輸層協議,主要解決數據 如何在網絡中傳輸,而HTTP是應用層協議,主要解決如何包裝數據,而socket則是對TCP/IP協議的封裝和應用(程序員層面上)。實際上http協議就是創建在tcp/ip協議之上的。,幾乎每一種語言都有本身的Http實現,固然也有本身的Socket實現,好比Golang、Java,在本身的net包裏均可以找到源代碼。使用TCP協議是須要鏈接三次握手,斷開鏈接四次揮手的。
HTTP 是無狀態協議,它不對以前發生過的請求和響應的狀態進行管理。也就是說,沒法根據以前的狀態進行本次的請求處理。可是使用Cookie和Session能夠保存狀態和識別。HTTP只能是由客戶端發起,服務端是沒法主動想客戶端發送數據的。安全
TCP(Transmission Control Protocol,傳輸控制協議)是OSI七層中傳輸層的協議。服務器
TCP(Transmission Control Protocol,傳輸控制協議)是基於鏈接的協議,也就是說,在正式收發數據前,必須和對方創建可靠的鏈接。TCP提供超時重發,丟棄重複數據,檢驗數據,流量控制等功能,保證數據能從一端傳到另外一端。 理想狀態下,TCP鏈接一旦創建,在通訊雙方中的任何一方主動關閉鏈接前,TCP 鏈接都將被一直保持下去。斷開鏈接時服務器和客戶端都可以主動發起斷開TCP鏈接的請求 。
安全體如今哪兒?
鏈接安全:三次握手 四次揮手,具體請參考:TCP詳解。
數據安全:TCP提供超時重發,丟棄重複數據,檢驗數據,流量控制等功能,保證數據能從一端傳到另外一端。網絡
解決網絡中的數據能夠安全無錯的傳送
HTTP協議是基於TCP的,因爲HTTP請求是一次請求一次應答,因爲請求和應答都只有一次,因此就必須保證數據的安全性,在這一次的傳送中很差丟失數據,因此HTTP是要基於更加安全的TCP協議而不是UDP協議,Socket鏈接能夠基於TCP也能夠基於UDP,看具體的業務的需求了。 HTTP請求使用基於TCP的Socket鏈接。
TCP發送的包有序號,對方收到包後要給一個反饋,若是超過必定時間還沒收到反饋就自動執行超時重發,所以TCP最大的優勢是可靠。通常網頁(http)、郵件(SMTP)、遠程鏈接(Telnet)、文件(FTP)傳送就用TCP 。框架
UDP (User Datagram Protocol,用戶數據報協議)是OSI參考模型中無鏈接的傳輸層協議.socket
UDP用戶數據報協議,是一個無鏈接的簡單的面向數據報的運輸層協議。UDP不提供可靠性,它只是把應用程序傳給IP層的數據報發送出去,可是並不能保證它們能到達目的地。因爲UDP在傳輸數據報前不用在客戶和服務器之間創建一個鏈接,且沒有超時重發等機制,故而傳輸速度很快。
解決網絡中的數據能夠高效的傳送
OSI參考模型中傳輸協議只有TCP和UDP兩種,TCP須要連接安全效率低,UDP無線鏈接不安全效率高,咱們平時使用作多的HTTP協議基於TCP,不少語言都有HTTP請求的封裝,用起來很方便,可是想使用UDP就沒那麼方便了,想使用UDP咱們就須要本身去寫一個Socket UDP了,Socket UDP不須要連接,客戶端知道服務端的IP和端口號直接發送數據就能夠了,Socket TCP因爲須要連接因此使用的時候須要心跳機制來確保連接沒有斷開。
UDP通常用於多點通訊和實時的數據業務,好比語音廣播、視頻、QQ、TFTP(簡單文件傳送)、SNMP(簡單網絡管理協議)、RTP(實時傳送協議)RIP(路由信息協議,如報告股票市場,航空信息)、DNS(域名解釋)。注重速度流暢。
socket是對TCP或者UDP協議的封裝和實現,socket並非協議,差很少每一種語言都實現了對TCP和UDP封裝和實現的Socket代碼庫,方便開發程序員使用。
socket是對TCP或者UDP協議的封裝和實現,這樣我就能夠基於你所使用語言的Socket來實現更多的功能,有基於Socket TCP的HTTP請求,有基於Socket TCP長鏈接的消息推送,也能夠基於Socket TCP/UDP自定義一套本身的通訊協議。
HTTP基於TCP,HTTP請求須要使用Socket TCP來完成。
因爲一次HTTP請求會涉及到HTTP TCP Socket DNS 等等,弄清楚一次HTTP的流程大概能夠知道網絡請求的原理。那麼咱們發送一次HTTP請求到底要經歷什麼?
一次HTTP請求和響應要經歷的幾個步驟:
域名解析介意是客戶端的工做,客戶端只有服務端的域名(相似www.baidu.com),並不知道服務端的IP地址,須要客戶端拿着域名到DNS服務器獲取域名對應的IP地址。
由客戶端發起,在三次握手後客戶端和服務端創建TCP鏈接。所謂三次握手(Three-way Handshake),是指創建一個TCP鏈接時,須要客戶端和服務器總共發送3個包。
三次握手的目的是鏈接服務器指定端口,創建TCP鏈接,並同步鏈接雙方的序列號和確認號並交換 TCP 窗口大小信息.在 Socket 編程中,客戶端執行connect()時。將觸發三次握手。
首先了解一下幾個標誌,SYN(synchronous),同步標誌,ACK (Acknowledgement),即確認標誌,seq應該是Sequence Number,序列號的意思,另外還有四次握手的fin,應該是final,表示結束標誌。
第一次握手:客戶端發送一個TCP的SYN標誌位置1的包指明客戶打算鏈接的服務器的端口,以及初始序號X,保存在包頭的序列號(Sequence Number)字段裏。
第二次握手:服務器發回確認包(ACK)應答。即SYN標誌位和ACK標誌位均爲1同時,將確認序號(Acknowledgement Number)設置爲客戶的序列號加1以,即X+1。
第三次握手:客戶端再次發送確認包(ACK) SYN標誌位爲0,ACK標誌位爲1。而且把服務器發來ACK的序號字段+1,放在肯定字段中發送給對方.而且在數據段放寫序列號的+1。
由客戶端發起,客戶端組裝好請求報文,向服務端發送HTTP請求,HTTP由固定的格式,具體想看下圖:
HTTP請求報文由3部分組成(請求行+請求頭+請求體),這三部分還有本身的組裝格式,這裏就不詳細說明了。
服務端收到客戶端的HTTP請求拿到請求報文後就響應請求,就是根據請求報文處理後發送數據到客戶端。服務端發送到客戶端的數據叫作響應報文,由服務端組裝,格式以下:
① 報文協議及版本;
② 狀態碼及狀態描述;
③ 響應報文頭,也是由多個屬性組成;
④ 響應報文體,即咱們真正要的「乾貨」。
在響應報文體裏面纔是咱們客戶端正真想要的東西,對於Android/IOS移動端來講通常都是Json數據,對於web瀏覽器來講通常都是HTML,客戶端得到響應報文後就處理數據。
通常狀況下TCP鏈接是因爲客戶端主動關閉的,關閉須要客戶端主動發起四次揮手,才能夠關閉TCP鏈接。通常狀況下,一旦請求和響應完成了,就要關閉TCP鏈接,而後若是客戶端或者服務器在其頭信息加入了這行代碼:Connection:keep-alive,TCP鏈接在發送後將仍然保持打開狀態,因而,客戶端能夠繼續經過相同的鏈接發送請求。保持鏈接節省了爲每一個請求創建新鏈接所需的時間,還節約了網絡帶寬。
TCP的鏈接的拆除須要發送四個包,所以稱爲四次揮手(four-way handshake)。客戶端或服務器都可主動發起揮手動做,在socket
編程中,任何一方執行close()操做便可產生揮手操做。
其實有個問題,爲何鏈接的時候是三次握手,關閉的時候倒是四次揮手?
由於當Server端收到Client端的SYN鏈接請求報文後,能夠直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來 同步的。可是關閉鏈接時,當Server端收到FIN報文時,極可能並不會當即關閉SOCKET,因此只能先回復一個ACK報文,告訴Client端,」 你發的FIN報文我收到了」。只有等到我Server端全部的報文都發送完了,我才能發送FIN報文,所以不能一塊兒發送。故須要四步握手。
舉例說明客戶端主動發送TCP關閉請求步驟:
第一次揮手:Client發送一個FIN,表示須要關閉Client到Server的數據傳送,Client進入FIN_WAIT_1狀態
第二次揮手:Server收到FIN後,發送一個ACK給Client,確認序號爲收到序號+1,Server進入CLOSE_WAIT狀態
第三次揮手:Server發送一個FIN,用來關閉Server到Client的數據傳送,Server進入LAST_ACK狀態
第四次揮手:Client收到FIN後,Client進入TIME_WAIT狀態,接着發送一個ACK給Server,確認序號爲收到序號+1,Server進入CLOSED狀態,完成四次揮手
最後圖解一次HTTP請求的心路歷程: