TCP 連接
手機等一些移動設備,能夠使用聯網功能是因為手機底層實現了 TCP/IP 協議,可以使手機終端通過無線網絡建立 TCP 連接。TCP 協議可以對上層網絡提供接口,使上層網絡數據的傳輸建立在"無差別"的網絡之上。
在具體介紹之前,先來弄清一些基本概念:
SYN(synchronous)是TCP/IP建立連接時使用的握手信號,表示建立連接
FIN 表示關閉連接
ACK(Acknowledgement)既確認字符,在數據通信中,接收站發給發送站的一種傳輸類控制字符。表示發來的數據已確認接收無誤,表示響應
LISTEN 表示服務器端的某個 SOCKET 處于監聽狀態,可以接受連接了。
MIME類型 在把輸出結果傳送到瀏覽器上的時候,瀏覽器必須啟動適當的應用程序來處理這個輸出文檔。這可以通過多種類型 MIME(多功能網際郵件擴充協議)來完成。在 HTTP 中,MIME 類型被定義在 Content-Type header 中。
URL 統一資源定位符(URL)也被稱為網頁地址,是因特網上標準的資源的地址,現在幾乎所有的URI都是URL。
第一部分是協議(或稱為服務方式)
第二部分是存有該資源的主機IP地址(有時也包括端口號)
第三部分是主機資源的具體位置(如目錄和文件名等)
第一部分和第三部分之間用** '://'** 符號隔開,第二部分和第三部分用** '/'**符號分隔。第一部分和第二部分是不可缺少的,第三部分有時也可以省略。
TCP 三層握手
我們要和服務端連接 TCP 連接,需要通過三次連接,包括:請求,確認,建立連接。即傳說中的"三次握手協議":
第一次握手:客戶端發送 syn 包(syn = j)到服務器,并進入 SYN_SEND 狀態,等待服務器確認
第二次握手:服務器收到 syn 包,必須確認客戶的 SYN(ack = j + 1),同時自己也發送一個 SYN 包(syn = k),即 SYN + ACK 包,此時服務器進入 SYN_RECV 狀態
第三次握手:客戶端收到服務器的 SYN + ACK 包,向服務器發送確認包 ACK(ack=k+1),此包發送完畢,客戶端和服務器進入 ESTABLISHED 狀態,完成三次握手
握手過程中傳送的包里不包含數據,三次握手完畢后,客戶端與服務器才正式開始傳送數據。
理想狀態下,TCP 連接一旦建立,在通信雙方中的任何一方主動關閉連接之前,TCP 連接都將被一直保持下去。
但是由于 TCP 連接是全雙工的,所以每個方向都必須單獨進行關閉。這原則是當一方完成它的數據發送任務后就能發送一個 FIN 來終止這個方向的連接。收到一個 FIN 只意味著這一方向上沒有數據流動,一個 TCP 連接在收到一個 FIN 后仍能發送數據。首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉。
TCP 四次揮手
斷開連接時服務器和客戶端均可以主動發起斷開 TCP 連接的請求,斷開過程需要經過"四次揮手"
第一次揮手:TCP 客戶端發送一個 FIN,用來關閉客戶到服務器的數據傳送。
第二次揮手:服務器收到這個 FIN,它發回一個 ACK,確認序號為收到的序號加 1。和 SYN 一樣,一個 FIN 將占用一個序號。
第三次揮手:服務器關閉客戶端的連接,發送一個 FIN 給客戶端。
第四次揮手:客戶端發回 ACK 報文確認,并將確認序號設置為收到序號加 1。
那么這里就會有一個問題了,為什么建立連接協議是三次握手,而關閉連接卻是四次握手呢?
這是因為服務端的 LISTEN 狀態下的 SOCKET 當收到 SYN 報文的建連請求后,它可以把 ACK 和 SYN(ACK 起應答作用,而 SYN 起同步作用)放在一個報文里來發送。
但關閉連接時,當收到對方的 FIN 報文通知時,它僅僅表示對方沒有數據發送給你了,但未必你所有的數據都全部發送給對方了,所以你可以未必會馬上會關閉 SOCKET
也即你可能還需要發送一些數據給對方之后,再發送 FIN 報文給對方來表示你同意現在可以關閉連接了,所以它這里的 ACK 報文和 FIN 報文多數情況下都是分開發送的.
HTTP 協議
HTTP 協議即超文本傳送協議(Hypertext Transfer Protocol),定義了瀏覽器怎樣向萬維網服務器請求萬維網文檔,以及服務器怎樣把文檔傳送給瀏覽器。
從層次的角度看,HTTP 是面向(transaction-oriented)應用層協議,它是萬維網上能夠可靠地交換文件(包括文本,聲音,圖像等各種多媒體文件)的重要基礎,也是 Web 聯網的基礎,也是手機聯網常用的協議之一,HTTP 協議是建立在 TCP 協議之上的一種應用。
工作流程
一次 HTTP 操作稱為一個事務,其工作過程可分為四步:
1)首先客戶機與服務器需要建立連接,只要單擊某個超級鏈接,HTTP 的工作開始。
2)建立連接后,客戶機發送一個請求給服務器,請求方式的格式為:統一資源標識符(URL)、協議版本號、后邊是 MIME 信息包括請求裝飾符、客戶機信息和可能的內容。
3)服務器接到請求后,給予相應的響應信息,其格式為一個狀態行,包括信息的協議版本號、一個成功或錯誤的代碼,后邊是 MIME 信息包含服務器信息、實體信息和可能的內容。
4)客戶端接收服務器所返回的信息通過瀏覽器顯示在用戶的顯示屏上,然后客戶機與服務器斷開連接。
如果在以上過程中的某一步出現錯誤,那么產生錯誤的信息將返回到客戶端,由顯示屏輸出,對于用戶來說,這些過程是由 HTTP 自己完成的,用戶只要用鼠標點擊,等待信息顯示就可以了。
這樣就限制了使用 HTTP 協議,無法實現在客戶端沒有發起請求的時候,服務器將消息推送給客戶端。
需要注意的是:HTTP 協議是一個無狀態的協議,同一個客戶端的這次請求和上次請求是沒有對應關系
HTTP 連接最顯著的特點是客戶端發送的每次請求都需要服務器回送響應(永遠都是客戶端發送請求,服務器回送響應),在請求結束后,會主動釋放連接。從建立連接到關閉連接的過程稱為"一次連接"。
1)在HTTP 1.0中,客戶端的每次請求都要求建立一次單獨的連接,在處理完本次請求后,就自動釋放連接。
2)在HTTP 1.1中則可以在一次連接中處理多個請求,并且多個請求可以重疊進行,不需要等待一個請求結束后再發送下一個請求。
由于 HTTP 在每次請求結束后都會主動釋放連接,因此 HTTP 連接是一種"短連接",要保持客戶端程序的在線狀態,需要不斷地向服務器發起連接請求。
通常的做法是即使不需要獲得任何數據,客戶端也保持每隔一段固定的時間向服務器發送一次"保持連接"的請求,服務器在收到該請求后對客戶端進行回復,表明知道客戶端"在線"。
若服務器長時間無法收到客戶端的請求,則認為客戶端"下線",若客戶端長時間無法收到服務器的回復,則認為網絡已經斷開。
socket
網絡上的兩個程序通過一個雙向的通信連接實現數據的交換,這個連接的一端稱為一個 socket。
套接字(socket)是通信的基石,是支持 TCP/IP 協議的網絡通信的基本操作單元。它是網絡通信過程中端點的抽象表示,包含進行網絡通信必須的五種信息:連接使用的協議,本地主機的 IP 地址,本地進程的協議端口,遠地主機的 IP 地址,遠地進程的協議端口。
應用層通過傳輸層進行數據通信時,TCP 會遇到同時為多個應用程序進程提供并發服務的問題。多個 TCP 連接或多個應用程序進程可能需要通過同一個 TCP 協議端口傳輸數據。
為了區別不同的應用程序進程和連接,許多計算機操作系統為應用程序與 TCP/IP 協議交互提供了套接字(Socket)接口。應用層可以和傳輸層通過 Socket 接口,區分來自不同應用程序進程或網絡連接的通信,實現數據傳輸的并發服務。
建立socket連接
建立 Socket 連接至少需要一對套接字,其中一個運行于客戶端,稱為 ClientSocket ,另一個運行于服務器端,稱為 ServerSocket 。
套接字之間的連接過程分為三個步驟:服務器監聽,客戶端請求,連接確認。
服務器監聽:服務器端套接字并不定位具體的客戶端套接字,而是處于等待連接的狀態,實時監控網絡狀態,等待客戶端的連接請求。
客戶端請求:指客戶端的套接字提出連接請求,要連接的目標是服務器端的套接字。為此,客戶端的套接字必須首先描述它要連接的服務器的套接字,指出服務器端套接字的地址和端口號,然后就向服務器端套接字提出連接請求。
連接確認:當服務器端套接字監聽到或者說接收到客戶端套接字的連接請求時,就響應客戶端套接字的請求,建立一個新的線程,把服務器端套接字的描述發給客戶 端,一旦客戶端確認了此描述,雙方就正式建立連接。而服務器端套接字繼續處于監聽狀態,繼續接收其他客戶端套接字的連接請求。
SOCKET 連接與 TCP 連接
創建 Socket 連接時,可以指定使用的傳輸層協議,Socket 可以支持不同的傳輸層協議(TCP 或 UDP(用戶數據報協議,與 TCP 協議一樣用于處理數據包,是一種無連接的協議)),當使用 TCP 協議進行連接時,該 Socket 連接就是一個 TCP 連接。
Socket 連接與 HTTP 連接
由于通常情況下 Socket 連接就是 TCP 連接,因此 Socket 連接一旦建立,通信雙方即可開始相互發送數據內容,直到雙方連接斷開。
但在實際網絡應用中,客戶端到服務器之間的通信往往需要穿越多個中間節點,例如路由器、網關、防火墻等,大部分防火墻默認會關閉長時間處于非活躍狀態的連接而導 致 Socket 連接斷連,因此需要通過輪詢告訴網絡,該連接處于活躍狀態。
而 HTTP 連接使用的是"請求-響應"的方式,不僅在請求時需要先建立連接,而且需要客戶端向服務器發出請求后,服務器端才能回復數據。
很多情況下,需要服務器端主動向客戶端推送數據,保持客戶端與服務器數據的實時與同步。
此時若雙方建立的是 Socket 連接,服務器就可以直接將數據傳送給 客戶端,若雙方建立的是 HTTP 連接,則服務器需要等到客戶端發送一次請求后才能將數據傳回給客戶端,因此,客戶端定時向服務器端發送連接請求,不僅可以保持在線,同時也是在"詢問"服務器是否有新的數據,如果有就將數據傳給客戶端。
總結
http 是要基于 TCP 連接基礎上的,簡單的說,TCP 就是單純建立連接,不涉及任何我們需要請求的實際數據,簡單的傳輸。http 是用來收發數據,即實際應用上來的。
TCP 是底層通訊協議,定義的是 數據傳輸和連接方式的規范
HTTP 是應用層協議,定義的是 傳輸數據的內容的規范
HTTP 協議中的數據是利用 TCP 協議傳輸的,所以支持 HTTP 也就一定支持 TCPHTTP 支持的是 www 服務,而 TCP/IP 是協議,它是 Internet 國際互聯網絡的基礎。
TCP/IP 是網絡中使用的基本的通信協議。
TCP/IP 實際上是一組協議,它包括上百個各種功能的協議,如:遠程登錄、文件傳輸和電子郵件等,而 TCP 協議和 IP 協議是保證數據完整傳輸的兩個基本的重要協議。通常說 TCP/IP 是 Internet 協議族,而不單單是 TCP 和 IP。
擴展:HTTP 響應碼信息
http 狀態返回代碼 1xx(臨時響應) 表示臨時響應并需要請求者繼續執行操作的狀態代碼。
100 (繼續) 請求者應當繼續提出請求。服務器返回此代碼表示已收到請求的第一部分,正在等待其余部分。
101 (切換協議) 請求者已要求服務器切換協議,服務器已確認并準備切換。
http狀態返回代碼 2xx (成功) 表示成功處理了請求的狀態代碼。
200 (成功) 服務器已成功處理了請求。 通常,這表示服務器提供了請求的網頁。
201 (已創建) 請求成功并且服務器創建了新的資源。
202 (已接受) 服務器已接受請求,但尚未處理。
203 (非授權信息) 服務器已成功處理了請求,但返回的信息可能來自另一來源。
204 (無內容) 服務器成功處理了請求,但沒有返回任何內容。
205 (重置內容) 服務器成功處理了請求,但沒有返回任何內容。
206 (部分內容) 服務器成功處理了部分 GET 請求。
http狀態返回代碼 3xx (重定向) 表示要完成請求,需要進一步操作。 通常,這些狀態代碼用來重定向。
300 (多種選擇) 針對請求,服務器可執行多種操作。 服務器可根據請求者 (user agent) 選擇一項操作,或提供操作列表供請求者選擇。
301 (永久移動) 請求的網頁已永久移動到新位置。 服務器返回此響應(對 GET 或 HEAD 請求的響應)時,會自動將請求者轉到新位置。
302 (臨時移動) 服務器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以后的請求。
303 (查看其他位置) 請求者應當對不同的位置使用單獨的 GET 請求來檢索響應時,服務器返回此代碼。
304 (未修改) 自從上次請求后,請求的網頁未修改過。 服務器返回此響應時,不會返回網頁內容。
305 (使用代理) 請求者只能使用代理訪問請求的網頁。 如果服務器返回此響應,還表示請求者應使用代理。
307 (臨時重定向) 服務器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以后的請求。
http狀態返回代碼 4xx(請求錯誤) 這些狀態代碼表示請求可能出錯,妨礙了服務器的處理。
400 (錯誤請求) 服務器不理解請求的語法。
401 (未授權) 請求要求身份驗證。 對于需要登錄的網頁,服務器可能返回此響應。
403 (禁止) 服務器拒絕請求。
404 (未找到) 服務器找不到請求的網頁。
405 (方法禁用) 禁用請求中指定的方法。
406 (不接受) 無法使用請求的內容特性響應請求的網頁。
407 (需要代理授權) 此狀態代碼與 401(未授權)類似,但指定請求者應當授權使用代理。
408 (請求超時) 服務器等候請求時發生超時。
409 (沖突) 服務器在完成請求時發生沖突。 服務器必須在響應中包含有關沖突的信息。
410 (已刪除) 如果請求的資源已永久刪除,服務器就會返回此響應。
411 (需要有效長度) 服務器不接受不含有效內容長度標頭字段的請求。
412 (未滿足前提條件) 服務器未滿足請求者在請求中設置的其中一個前提條件。
413 (請求實體過大) 服務器無法處理請求,因為請求實體過大,超出服務器的處理能力。
414 (請求的 URI 過長) 請求的 URI(通常為網址)過長,服務器無法處理。
415 (不支持的媒體類型) 請求的格式不受請求頁面的支持。
416 (請求范圍不符合要求) 如果頁面無法提供請求的范圍,則服務器會返回此狀態代碼。
417 (未滿足期望值) 服務器未滿足"期望"請求標頭字段的要求。
http狀態返回代碼 5xx(服務器錯誤) 這些狀態代碼表示服務器在嘗試處理請求時發生內部錯誤。 這些錯誤可能是服務器本身的錯誤,而不是請求出錯。
500 (服務器內部錯誤) 服務器遇到錯誤,無法完成請求。
501 (尚未實施) 服務器不具備完成請求的功能。 例如,服務器無法識別請求方法時可能會返回此代碼。
502 (錯誤網關) 服務器作為網關或代理,從上游服務器收到無效響應。
503 (服務不可用) 服務器目前無法使用(由于超載或停機維護)。 通常,這只是暫時狀態。
504 (網關超時) 服務器作為網關或代理,但是沒有及時從上游服務器收到請求。
505 (HTTP 版本不受支持) 服務器不支持請求中所用的 HTTP 協議版本。
擴展:HTTP 協議的特點
支持客戶/服務器模式。
簡單快速:客戶向服務器請求服務時,只需要傳送請求方法和路徑,請求方法常用的有 GET,POST,HEAD 等,每種方法規定了客戶與服務器聯系的類型不同。由于 HTTP 協議簡單,使得 HTTP 服務器的程序規模小,因而通訊速度很快。
靈活:HTTP 允許傳輸任意類型的數據對象。正在傳輸的類型由 Content-Type 加以標記。
無連接:無連接的含義是限制每次連接只處理一個請求,服務器處理完客戶的請求并收到客戶的應答后,即斷開連接。采用這種方式可以節省傳輸時間。
無狀態:HTTP 協議是無狀態協議。無狀態是指協議對于事物處理沒有記憶能力,缺少狀態意味著如果后續處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數據量增大,另一方面,在服務器不需要先前信息的時候它的應答就較快。
擴展:HTTP 2.0
HTTP 2.0 的出現,相比于 HTTP 1.x ,大幅度的提升了 web 性能。在與 HTTP/1.1 完全語義兼容的基礎上,進一步減少了網絡延遲。
多路復用 (Multiplexing)
多路復用允許同時通過單一的 HTTP/2 連接發起多重的請求-響應消息。
眾所周知 ,在 HTTP/1.1 協議中 「瀏覽器客戶端在同一時間,針對同一域名下的請求有一定數量限制。超過限制數目的請求會被阻塞」。
而 HTTP/2 的多路復用(Multiplexing) 則允許同時通過單一的 HTTP/2 連接發起多重的請求-響應消息。
因此 HTTP/2 可以很容易的去實現多流并行而不用依賴建立多個 TCP 連接,HTTP/2 把 HTTP 協議通信的基本單位縮小為一個一個的幀,這些幀對應著邏輯流中的消息。并行地在同一個 TCP 連接上雙向交換消息。
更多可見: HTTP/2.0 相比 1.0 有哪些重大改進?