通訊協議 -- HTTP、TCP、UDP

CP  HTTP  UDP:html

都是通訊協議,也就是通訊時所遵照的規則,只有雙方按照這個規則,對方纔能理解併爲之服務web

TCP   HTTP   UDP三者的關係:瀏覽器

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

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

在傳輸層有TCP和UDP協議服務器

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

所以,HTTP自己就是一個協議,是從web服務器傳輸超文本到本地瀏覽器的傳輸協議。網絡

socket:session

這是爲了實現以上的通訊過程而創建成來的通訊管道,其真實的表明是客戶端和服務器端的一個通訊進程,雙方進程經過socket進行通訊,而通訊的規則採用指定的協議。socket只是一種鏈接模式,不是協議,tcp,udp,簡單的說(雖然不許確)是兩個最基本的協議,不少其它協議都是基於這兩個協議如,http就是基於tcp的,.用socket能夠建立tcp鏈接,也能夠建立udp鏈接,這意味着,用socket能夠建立任何協議的鏈接,由於其它協議都是基於此的。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協議。

相關文章
相關標籤/搜索