1. 程式人生 > >通信協議 -- HTTP、TCP、UDP

通信協議 -- HTTP、TCP、UDP

gb2312 分鐘 per 保持 操作系統 告訴 如果 html 域名

CP HTTP UDP:

都是通信協議,也就是通信時所遵守的規則,只有雙方按照這個規則,對方才能理解並為之服務

TCP HTTP UDP三者的關系:

TCP/IP是一個協議組,可分為四個層次:網絡接口層、網絡層、傳輸層和應用層

在網絡層有IP協議、ICMP協議、ARP協議和BOOTP協議

在傳輸層有TCP和UDP協議

在應用層有FTP、HTTP、TELNET、SMTP、DNS等協議

因此,HTTP本身就是一個協議,是從web服務器傳輸超文本到本地瀏覽器的傳輸協議。

socket:

這是為了實現以上的通信過程而建立成來的通信管道,其真實的代表是客戶端和服務器端的一個通信進程,雙方進程通過socket進行通信,而通信的規則采用指定的協議。socket只是一種連接模式,不是協議,tcp,udp,簡單的說(雖然不準確)是兩個最基本的協議,很多其它協議都是基於這兩個協議如,http就是基於tcp的,.用socket可以創建tcp連接,也可以創建udp連接,這意味著,用socket可以創建任何協議的連接,因為其它協議都是基於此的。

什麽是HTTP協議

HTTP全稱是HyperText Transfer Protocal,即:超文本傳輸協議,Http是應用層協議,當你上網瀏覽網頁的時候,瀏覽器和Web服務器之間就會通過HTTP進行數據的發送和接收。Http是一個基於請求/響應模式的、無狀態的協議。即我們通常所說的Request/Response。

HTTP的連接:

無狀態:指的是服務器無法知道2次請求之間的聯系,即使是前後兩次是同一個瀏覽器,也沒有任何數據能夠判斷出是同一個瀏覽器的請求,後來可以通過cookie、session來判斷

有連接:因為它是基於TCP協議,是面向連接的,需要3次握手,4次斷開。

短連接:http1.1之前,都是一個請求一個連接,而tcp的連接創建銷毀成本高,對服務器又很大的影響,所以,自http1.1開始,支持keep-alive,默認開啟,一個連接打開之後,會保持一段時間,瀏覽器再訪問該服務器就使用這個tcp連接,減輕了服務器壓力,提高了效率。

URL

URL(Uniform Resource Locator) 地址用於描述一個網絡上的資源, 基本格式如下

schema://host[:port#]/path/.../[?query-string][#anchor]

scheme 指定低層使用的協議(例如:http, https, ftp)

host HTTP服務器的IP地址或者域名

port# HTTP服務器的默認端口是80,這種情況下端口號可以省略。如果使用了別的端口,必須指明,例如 http://www.cnblogs.com:8080/

path 訪問資源的路徑

query-string 發送給http服務器的數據

anchor- 錨

HTTP的Request/Response:

先看Request消息的結構,Request消息分為3部分:Request line,Request header,Request body,在header和body之間有一個空行

技術分享圖片

第一行Request line中包含:請求方法,資源路徑,協議版本號

第二行Request header中:

Accept

作用: 瀏覽器端可以接受的媒體類型,

例如: Accept: text/html 代表瀏覽器可以接受服務器回發的類型為 text/html 也就是我們常說的html文檔,

如果服務器無法返回text/html類型的數據,服務器應該返回一個406錯誤(non acceptable)

通配符 * 代表任意類型

例如 Accept: */* 代表瀏覽器可以處理所有類型,(一般瀏覽器發給服務器都是發這個)

Referer:

作用: 提供了Request的上下文信息的服務器,告訴服務器我是從哪個鏈接過來的,比如從我主頁上鏈接到一個朋友那裏,他的服務器就能夠從HTTP Referer中統計出每天有多少用戶點擊我主頁上的鏈接訪問他的網站。

例如: Referer:http://translate.google.cn/?hl=zh-cn&tab=wT

Accept-Language

作用: 瀏覽器申明自己接收的語言。

語言跟字符集的區別:中文是語言,中文有多種字符集,比如big5,gb2312,gbk等等;

例如: Accept-Language: en-us

Accept-Encoding

作用: 瀏覽器申明自己接收的編碼方法,通常指定壓縮方法,是否支持壓縮,支持什麽壓縮方法(gzip,deflate)

User-Agent

作用:告訴HTTP服務器, 客戶端使用的操作系統和瀏覽器的名稱和版本.

Connection

例如: Connection: keep-alive 當一個網頁打開完成後,客戶端和服務器之間用於傳輸HTTP數據的TCP連接不會關閉,如果客戶端再次訪問這個服務器上的網頁,會繼續使用這一條已經建立的連接

例如: Connection: close 代表一個Request完成後,客戶端和服務器之間用於傳輸HTTP數據的TCP連接會關閉, 當客戶端再次發送Request,需要重新建立TCP連接。

Pragma

作用: 防止頁面被緩存, 在HTTP/1.1版本中,它和Cache-Control:no-cache作用一模一樣

Pargma只有一個用法, 例如: Pragma: no-cache

Cookie:

作用: 最重要的header, 將cookie的值發送給HTTP 服務器

Accept-Charset

作用:瀏覽器申明自己接收的字符集,這就是本文前面介紹的各種字符集和字符編碼,如gb2312,utf-8

Response消息結構和Request消息結構基本一樣,也分為三部分:Request line,Request header,Request body,在header和body之間有一個空行

技術分享圖片

第一行包含:HTTP協議版本號,狀態碼(200)和信息(ok)

第二行Response Header包含:

Cache-Control

作用: 這個是非常重要的規則。 這個用來指定Response-Request遵循的緩存機制。各個指令含義如下

Cache-Control:Public 可以被任何緩存所緩存()

Cache-Control:Private 內容只緩存到私有緩存中

Cache-Control:no-cache 所有內容都不會被緩存

Content-Type

作用:WEB服務器告訴瀏覽器自己響應的對象的類型和字符集,

Expires

作用: 瀏覽器會在指定過期時間內使用本地緩存

例如: Expires: Tue, 08 Feb 2022 11:35:14 GMT

Last-Modified:

作用: 用於指示資源的最後修改日期和時間。

Server:

作用:指明HTTP服務器的軟件信息

例如:Server: Microsoft-IIS/7.5

X-AspNet-Version:

作用:如果網站是用ASP.NET開發的,這個header用來表示ASP.NET的版本

X-Powered-By:

作用:表示網站是用什麽技術開發的

Connection

例如: Connection: keep-alive 當一個網頁打開完成後,客戶端和服務器之間用於傳輸HTTP數據的TCP連接不會關閉,如果客戶端再次訪問這個服務器上的網頁,會繼續使用這一條已經建立的連接

例如: Connection: close 代表一個Request完成後,客戶端和服務器之間用於傳輸HTTP數據的TCP連接會關閉, 當客戶端再次發送Request,需要重新建立TCP連接。

Date

作用: 生成消息的具體時間和日期

例如: Date: Sat, 11 Feb 2012 11:35:14 GMT

HTTP協議之GetPost

Http協議定義了很多與服務器交互的方法,最基本的有4種,分別是GET,POST,PUT,DELETE. 一個URL地址用於描述一個網絡上的資源,而HTTP中的GET, POST, PUT, DELETE就對應著對這個資源的查,改,增,刪4個操作。 我們最常見的就是GET和POST了。GET一般用於獲取/查詢資源信息,而POST一般用於更新資源信息.

我們看看GET和POST的區別

1. GET提交的數據會放在URL之後,以?分割URL和傳輸數據,參數之間以&相連,如EditPosts.aspx?name=test1&id=123456. POST方法是把提交的數據放在HTTP包的Body中.

2. GET提交的數據大小有限制(因為瀏覽器對URL的長度有限制),而POST方法提交的數據沒有限制.

3. GET方式需要使用Request.QueryString來取得變量的值,而POST方式通過Request.Form來獲取變量的值,也就是說Get是通過地址欄來傳值,而Post是通過提交表單來傳值。

4. GET方式提交數據,會帶來安全問題,比如一個登錄頁面,通過GET方式提交數據時,用戶名和密碼將出現在URL上,如果頁面可以被緩存或者其他人可以訪問這臺機器,就可以從歷史記錄獲得該用戶的賬號和密碼.

TCP:

傳輸控制協議,就是對數據的傳輸進行一定的控制

連接管理機制:正常情況下,tcp需要經過三次握手建立連接,四次揮手斷開連接

三次握手:

技術分享圖片

剛開始, 客戶端和服務器都處於 CLOSE 狀態.
此時, 客戶端向服務器主動發出連接請求, 服務器被動接受連接請求.

1, TCP服務器進程先創建傳輸控制塊TCB, 時刻準備接受客戶端進程的連接請求, 此時服務器就進入了 LISTEN(監聽)狀態
2, TCP客戶端進程也是先創建傳輸控制塊TCB, 然後向服務器發出連接請求報文,此時報文首部中的同步標誌位SYN=1, 同時選擇一個初始序列號 seq = x, 此時,TCP客戶端進程進入了 SYN-SENT(同步已發送狀態)狀態。TCP規定, SYN報文段(SYN=1的報文段)不能攜帶數據,但需要消耗掉一個序號。
3, TCP服務器收到請求報文後, 如果同意連接, 則發出確認報文。確認報文中的 ACK=1, SYN=1, 確認序號是 x+1, 同時也要為自己初始化一個序列號 seq = y, 此時, TCP服務器進程進入了SYN-RCVD(同步收到)狀態。這個報文也不能攜帶數據, 但是同樣要消耗一個序號。
4, TCP客戶端進程收到確認後還, 要向服務器給出確認。確認報文的ACK=1,確認序號是 y+1,自己的序列號是 x+1.
5, 此時,TCP連接建立,客戶端進入ESTABLISHED(已建立連接)狀態。當服務器收到客戶端的確認後也進入ESTABLISHED狀態,此後雙方就可以開始通信了。

第一次:
客戶端 - - > 服務器 此時服務器知道了客戶端要建立連接了
第二次:
客戶端 < - - 服務器 此時客戶端知道服務器收到連接請求了
第三次:
客戶端 - - > 服務器 此時服務器知道客戶端收到了自己的回應

到這裏, 就可以認為客戶端與服務器已經建立了連接.


為什麽不用兩次握手?

主要是為了防止已經失效的連接請求報文突然又傳送到了服務器,從而產生錯誤。如果使用的是兩次握手建立連接,假設有這樣一種場景,客戶端發送的第一個請求連接並且沒有丟失,只是因為在網絡中滯留的時間太長了,由於TCP的客戶端遲遲沒有收到確認報文,以為服務器沒有收到,此時重新向服務器發送這條報文,此後客戶端和服務器經過兩次握手完成連接,傳輸數據,然後關閉連接。此時之前滯留的那一次請求連接,因為網絡通暢了, 到達了服務器,這個報文本該是失效的,但是,兩次握手的機制將會讓客戶端和服務器再次建立連接,這將導致不必要的錯誤和資源的費。
如果采用的是三次握手,就算是那一次失效的報文傳送過來了,服務端接受到了那條失效報文並且回復了確認報文,但是客戶端不會再次發出確認。由於服務器收不到確認,就知道客戶端並沒有請求連接。

為什麽不用四次?

因為三次已經可以滿足需要了, 四次就多余了.

四次揮手斷開

技術分享圖片

數據傳輸完畢後,雙方都可以釋放連接.
此時客戶端和服務器都是處於ESTABLISHED狀態,然後客戶端主動斷開連接,服務器被動斷開連接.

1, 客戶端進程發出連接釋放報文,並且停止發送數據。
釋放數據報文首部,FIN=1,其序列號為seq=u(等於前面已經傳送過來的數據的最後一個字節的序號加1),此時客戶端進入FIN-WAIT-1(終止等待1)狀態。 TCP規定,FIN報文段即使不攜帶數據,也要消耗一個序號。
2, 服務器收到連接釋放報文,發出確認報文,ACK=1,確認序號為 u+1,並且帶上自己的序列號seq=v,此時服務端就進入了CLOSE-WAIT(關閉等待)狀態。
TCP服務器通知高層的應用進程,客戶端向服務器的方向就釋放了,這時候處於半關閉狀態,即客戶端已經沒有數據要發送了,但是服務器若發送數據,客戶端依然要接受。這個狀態還要持續一段時間,也就是整個CLOSE-WAIT狀態持續的時間。
3, 客戶端收到服務器的確認請求後,此時客戶端就進入FIN-WAIT-2(終止等待2)狀態,等待服務器發送連接釋放報文(在這之前還需要接受服務器發送的最終數據)
4, 服務器將最後的數據發送完畢後,就向客戶端發送連接釋放報文,FIN=1,確認序號為v+1,由於在半關閉狀態,服務器很可能又發送了一些數據,假定此時的序列號為seq=w,此時,服務器就進入了LAST-ACK(最後確認)狀態,等待客戶端的確認。
5, 客戶端收到服務器的連接釋放報文後,必須發出確認,ACK=1,確認序號為w+1,而自己的序列號是u+1,此時,客戶端就進入了TIME-WAIT(時間等待)狀態。註意此時TCP連接還沒有釋放,必須經過2∗MSL(最長報文段壽命)的時間後,當客戶端撤銷相應的TCB後,才進入CLOSED狀態。
6, 服務器只要收到了客戶端發出的確認,立即進入CLOSED狀態。同樣,撤銷TCB後,就結束了這次的TCP連接。可以看到,服務器結束TCP連接的時間要比客戶端早一些。

為什麽最後客戶端還要等待 2*MSL的時間呢?

MSL(Maximum Segment Lifetime),TCP允許不同的實現可以設置不同的MSL值。

第一,保證客戶端發送的最後一個ACK報文能夠到達服務器,因為這個ACK報文可能丟失,站在服務器的角度看來,我已經發送了FIN+ACK報文請求斷開了,客戶端還沒有給我回應,應該是我發送的請求斷開報文它沒有收到,於是服務器又會重新發送一次,而客戶端就能在這個2MSL時間段內收到這個重傳的報文,接著給出回應報文,並且會重啟2MSL計時器。

第二,防止類似與“三次握手”中提到了的“已經失效的連接請求報文段”出現在本連接中。客戶端發送完最後一個確認報文後,在這個2MSL時間中,就可以使本連接持續的時間內所產生的所有報文段都從網絡中消失。這樣新的連接中不會出現舊連接的請求報文。

為什麽建立連接是三次握手,關閉連接確是四次揮手呢?

建立連接的時候, 服務器在LISTEN狀態下,收到建立連接請求的SYN報文後,把ACK和SYN放在一個報文裏發送給客戶端。
而關閉連接時,服務器收到對方的FIN報文時,僅僅表示對方不再發送數據了但是還能接收數據,而自己也未必全部數據都發送給對方了,所以己方可以立即關閉,也可以發送一些數據給對方後,再發送FIN報文給對方來表示同意現在關閉連接,因此,己方ACK和FIN一般都會分開發送,從而導致多了一次。

如果已經建立了連接, 但是客戶端突發故障了怎麽辦?

TCP設有一個保活計時器,顯然,客戶端如果出現故障,服務器不能一直等下去,白白浪費資源。服務器每收到一次客戶端的請求後都會重新復位這個計時器,時間通常是設置為2小時,若兩小時還沒有收到客戶端的任何數據,服務器就會發送一個探測報文段,以後每隔75分鐘發送一次。若一連發送10個探測報文仍然沒反應,服務器就認為客戶端出了故障,接著就關閉連接。

UDP用戶數據報協議,是一個無連接的簡單的面向數據報的運輸層協議,UDP不提供可靠性,它只是把應用程序傳給IP層的數據報發送出去,但是並不能保證它們能到達目的地。由於UDP在傳輸數據報前不用在客戶和服務器之間建立一個連接,且沒有超時重發等機制,故而傳輸速度很快。‘

應用場景,視頻、音頻傳輸,海量數據采集,一般來說,丟些包,問題不大,可以重新發送來解決。一般來說,UDP性能優於TCP,但是可靠性能要求高的場合還是選擇TCP協議。

通信協議 -- HTTP、TCP、UDP