TCP、HTTP協議HTTP請求完整過程(附TCP工作方式)



我所整理的東西都是曾經看視頻,帖子,或者某個大佬說的話最后寫成的筆記。現在相當於把筆記重新整理成一篇文章。所以哪怕有一些引用也找不到出處了,就不標明了!

什么是HTTP協議?

HTTP協議是超文本傳輸協議(默認端口80)。
服務器傳輸超文本到本地瀏覽器的傳送協議。
HTTP是一個基於TCP/IP通信協議來傳送數據的。
HTTP就是客服端→服務端的數據傳輸。
大致工作流程:
(1)客戶與服務器建立連接;
(2)客戶向服務器提出請求;
(3)服務器接受請求,並根據請求返回相應的文件作為應答;
(4)客戶與服務器關閉連接。

HTTP的特征:

1. 無連接(HTTP 的設計者有意利用這種特點將協議設計為請求時建連接、請求完釋放連接,以盡快將資源釋放出來服務其他客戶端。)。
正常默認是短鏈接:建立連接→傳送數據→關閉連接。
但是隨着發展,發現有時候每次訪問都需要建立一次 TCP 連接就顯得很低效。后來,Keep-Alive 被提出用來解決這效率低的問題。就是長連接
可以設置為長連接:建立連接→傳送數據→傳送數據→...→關閉連接。
其實長連接還分為兩種(完全理論知識,我沒實際操作過。視頻里講的):

  • without pipdining:收到上一個請求響應后才能發下一個。
  • with pipdining:不管響沒響應,都可以再發請求。

長短連接的優缺點:
像WEB網站的http服務一般都用短鏈接,因為長連接對於服務端來說會耗費一定的資源,而像WEB網站這么頻繁的成千上萬甚至上億客戶端的連接用短連接會更省一些資源,如果用長連接,而且同時有成千上萬的用戶,如果每個用戶都占用一個連接的話,那可想而知吧。所以並發量大,但每個用戶無需頻繁操作情況下需用短連好。

長連接是為了節省每次請求都要建立新連接所需要的時間,還節約帶寬。多用於操作頻繁,點對點的通訊,而且連接數不能太多情況。每個TCP連接都需要三步握手,這需要時間,如果每個操作都是先連接,再操作的話那么處理速度會降低很多,所以每個操作完后都不斷開,次處理時直接發送數據包就OK了,不用建立TCP連接。例如:數據庫的連接用長連接, 如果用短連接頻繁的通信會造成socket錯誤,而且頻繁的socket 創建也是對資源的浪費。
2. HTTP是媒體獨立的(不同的地方有不同的說法,我這里按照視頻里講解的說了。我也在別的地方看到的http特點不是這么講的,別較真)。
因為tcp傳輸的是報文段,所以任何類型都可以傳輸。只要客戶端和服務端達成一致即可。
3. HTTP是無狀態的(這個無連接和無狀態是統一說法,沒啥好撕的)。
通俗一點的理解就是:啥也不記。
優缺點都有:缺點是如果需要之前的數據必須重新傳,比較麻煩。但是如果不需要數據則正好,應答較快。
這里有一點要注意:HTTP 是一個無狀態協議,這意味着每個請求都是獨立的,Keep-Alive 沒能改變這個結果。所以我們所謂的長連接只不過不用每次新建連接,但是每一次的請求還是獨立的。
這些就是我之前在視頻里看到的並且總結的知識點。然后因為寫這篇文章所以還額外找了一些資料。看到了另一種關於http特征的說法,在這里粘貼一下,文章的最后我會貼上參考鏈接的。

HTTP協議的主要特點可概括如下:
1.支持客戶/服務器模式。
2.簡單快速:客戶向服務器請求服務時,只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。每種方法規定了客戶與服務器聯系的類型不同。由於HTTP協議簡單,使得HTTP服務器的程序規模小,因而通信速度很快。
3.靈活:HTTP允許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type(Content-Type是HTTP包中用來表示內容類型的標識)加以標記。
4.無連接:無連接的含義是限制每次連接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答后,即斷開連接。采用這種方式可以節省傳輸時間。
5.無狀態:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺少狀態意味着如果后續處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數據量增大。另一方面,在服務器不需要先前信息時它的應答就較快。

我們通過對比可以發現,其實主要的兩個不改變的就是無狀態,無連接。然后這里的簡單快速和靈活的原因就是因為支持客戶/服務器模式。也就是媒體獨立。總的來說,大概意思是差不多的。

更多HTTP面試資料、筆記添加微信:YDT939獲取,還有更多java專題面試資料等你來拿!

TCP協議 (傳輸控制協議)

上面說http的時候一直有提到tcp協議。這里專門講一下什么是tcp協議:

傳輸控制協議(TCP,Transmission Control Protocol)是為了在不可靠的互聯網絡上提供可靠的端到端字節流而專門設計的一個傳輸協議。

這個是百度百科的介紹。其實很好理解。為了端到端的數據傳輸而專門設計的。
用一個我個人的想象的理解:旅行箱/書包/塑料袋是為了我們在一個地方到另一個地方的攜帶/運輸而設計的。如果我從超市買一大堆東西,沒有任何包裝工具(袋子,箱子,盒子啥的),一起在懷里捧着,可能到家會發現半路上丟了東西。本來想吃火鍋,啥都買好了捧到家發現火鍋料丟了。完了,整個計划都不能實現了。
同樣的道理,兩個端數據傳輸,我們起碼得保證傳送的和接受的要一樣吧?不然一會兒丟個字節,一會兒丟個段落,最后傳過去的東西接收方都看不明白,那還有什么意義了?由此,tcp就是這么一個保證文件傳輸過程中不會丟減字節的協議。
接下來我直接貼上百度百科對tcp的介紹,有空的同學可以看一下,不太復雜。

TCP是一種面向廣域網的通信協議,目的是在跨越多個網絡通信時,為兩個通信端點之間提供一條具有下列特點的通信方式: [1]
(1)基於流的方式;
(2)面向連接;
(3)可靠通信方式;
(4)在網絡狀況不佳的時候盡量降低系統由於重傳帶來的帶寬開銷;
(5)通信連接維護是面向通信的兩個端點的,而不考慮中間網段和節點。
為滿足TCP協議的這些特點,TCP協議做了如下的規定: [10]
①數據分片:在發送端對用戶數據進行分片,在接收端進行重組,由TCP確定分片的大小並控制分片和重組;
②到達確認:接收端接收到分片數據時,根據分片數據序號向發送端發送一個確認;
③超時重發:發送方在發送分片時啟動超時定時器,如果在定時器超時之后沒有收到相應的確認,重發分片;
④滑動窗口:TCP連接每一方的接收緩沖空間大小都固定,接收端只允許另一端發送接收端緩沖區所能接納的數據,TCP在滑動窗口的基礎上提供流量控制,防止較快主機致使較慢主機的緩沖區溢出;
⑤失序處理:作為IP數據報來傳輸的TCP分片到達時可能會失序,TCP將對收到的數據進行重新排序,將收到的數據以正確的順序交給應用層;
⑥重復處理:作為IP數據報來傳輸的TCP分片會發生重復,TCP的接收端必須丟棄重復的數據;
⑦數據校驗:TCP將保持它首部和數據的檢驗和,這是一個端到端的檢驗和,目的是檢測數據在傳輸過程中的任何變化。如果收到分片的檢驗和有差錯,TCP將丟棄這個分片,並不確認收到此報文段導致對端超時並重發。

上面的通信方式讓我們對tcp有一個更清晰的認識。
下面的規定都是為了保證傳遞過程中數據不會變。保證發送的和接受的是一樣一樣的東西。(就好像塑料袋的作用是裝進袋子里的東西和到家以后從袋子里拿出來的東西是一樣的。別跟我說什么袋子壞掉了,路上偷吃了什么的情況啊!!!)然后我覺得概念還好理解。而且做法也通俗易懂的。一會兒下面還會有提到。

IP

IP地址是IP協議提供的一種統一的地址格式,它為互聯網上的每一個網絡和每一台主機分配一個邏輯地址,以此來屏蔽物理地址的差異。
其實覺得沒啥必要單獨講這個,但是寫到這里了,為了統一格式就這樣吧,所以ip也單獨列出來了。

TCP/IP協議

剛剛關於tcp和IP都單獨講了。現在我們就說說這一組協議。

TCP/IP協議(傳輸控制協議/互聯網協議)不是簡單的一個協議,而是一組特別的協議,包括:TCP,IP,UDP,ARP等,這些被稱為子協議。在這些協議中,最重要、最著名的就是TCP和IP。因此,大部分網絡管理員稱整個協議族為“TCP/IP”。
————來源百度百科

就是tcp知識一個傳輸的協議。我們平時兩台電腦上的互相發送信息,是ip協議確定哪兩台電腦,然后tcp協議來確確實實是傳輸數據。

TCP的三次握手

額,這個問題我在好幾天的的面經里就提過了,不過今天既然總結到這里了就當復習,重新說一下。
首先明確一點:每次通信都是客戶端主動連接服務端的。我們做項目的應該能理解這個。Java之所以是后端開發,人家寫頁面的之所以是前端開發(我沒任何鄙視的意思,就是一個形象的比喻),就是因為每次都是前端調用后端的接口,你做過后端主動去調用前端的啥啥啥?同樣這個道理,服務器就跟個飯店似的,一直在那開着,客戶端相當於客人,想去吃飯可以進去,然后點菜。但是不能飯店自己主動做個菜強迫某人買吧?
我先言語上大概敘述一下tcp通信的過程,然后有必要直接貼個圖上來。
我剛剛尋思怎么解釋這個三次握手尋思的我自己都樂的不行。其實如果你想象力和我一樣豐富的話,會覺得知識里真的好多樂趣。
我大概說一下,tcp建立一個連接需要三次握手,而終止一個連接要經過四次揮手,這是由TCP的半關閉(half-close)造成的。

建立連接:

  1. 客戶端發送SYN(SEQ=x)報文給服務器端,進入SYN_SEND狀態。
    (我們可以想象成客戶端給服務端發個消息:大哥,聊聊?
    這里的SYN,和SYN_SEND狀態,Established狀態,有興趣的自己去找找。個人感覺就像數據庫常量定義似的,沒啥絕對的意義。)
  2. 服務器端收到SYN報文,回應一個SYN (SEQ=y)ACK(ACK=x+1)報文,進入SYN_RECV狀態。
    (服務端收到客戶端消息了,尋思反正也沒啥事,聊聊就聊聊吧。然后說:行,我是XX,你要是沒找錯人,聊一會兒也行!)
  3. 客戶端收到服務器端的SYN報文,回應一個ACK(ACK=y+1)報文,進入Established狀態
    (客戶端收到服務端回復說能聊,回了個字:沒找錯人,就是你。然后這個時候倆人,不對,兩台電腦就可以開始傳數據了。)

其實咋說呢,我們說的三次握手就是三次數據的傳輸(個人理解,我不知道准不准確)。就跟你微信跟人聊天似的,
你跟人先說話,給人家發一條:在么?方便么?我發語音了啊?(直男第一問候語)。
人家回你:在,有空,發吧。
你還欠兒欠兒的回了句:那我發了啊!
然后才開始彈語音。
你看看,這是不是也是三條數據?tcp的三次握手我個人感覺就是這樣。

 

三次握手圖解

更多HTTP面試資料、筆記添加微信:YDT939獲取,還有更多java專題面試資料等你來拿!

結束連接:

  1. 某個應用進程首先調用close,稱該端執行“主動關閉”(active close)。該端的TCP於是發送一個FIN分節,表示數據發送完畢。
    (繼續上文,那個片發出去了,然后你的電腦上顯示發送完畢了。然后你打字說:發完了。)

  2. 接收到這個FIN的對端執行 “被動關閉”(passive close),這個FIN由TCP確認。
    (接收方也直接下載下來了。回了句:嗯,我也下載完了。)

  3. 一段時間后,接收到這個文件結束符的應用進程將調用close關閉它的套接字。這導致它的TCP也發送一個FIN。
    (接收方緊接着又發了一條消息:謝了啊兄弟,我看電影去了啊,拜拜)

  4. 接收這個最終FIN的原發送端TCP(即執行主動關閉的那一端)確認這個FIN。
    (你這個發片的看到以后回復:行,兄弟你忙去吧,注意身體啊,拜拜)

到了這里,你們骯臟的py交易就結束了。連接也結束了。再想聯系又要創建一個新的連接了。然后我上一下正經的結束連接的圖吧。我也不知道我講明白沒有,反正笑得挺歡。腦補是個好東西啊。

 

tcp連接的終止

然后TCP的三次握手,和工作過程我感覺也就這樣了。好多細節之類的想知道自己去查一些權威資料吧。

HTTP工作過程

最后說一下HTTP的工作流程。
假如你仔細看了上面的內容,應該可以直接理解這個圖了。HTTP是一個簡單的請求-響應協議,它通常運行在TCP之上。它指定了客戶端可能發送給服務器什么樣的消息以及得到什么樣的響應。然后下圖是一次完整的數據傳送過程。我真的寫不來各種繪圖,所以一般復雜一點,段落說不清的我直接手繪傳圖了。我盡量寫的字標准一點,起碼能認出來。


http工作過程

 

然后這篇文章就這樣了。有不同意見或者我哪里理解錯了說的有問題的歡迎指出,評論或者私聊都可以。共同交流進步嘛!再重申一點!!!我這些也都是看視頻,看百度百科,查資料啥的,還要加上自己的一些理解,最后寫出來的。可能有的地方沒說的很透或者說的很淺薄,歡迎指錯。

HTTP超全思維導圖:



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM