一、協議介紹
HTTP(HyperText Transfer Protocol,超文本傳輸協議)是一套計算機通過網絡進行通信的規則,使HTTP客戶端能夠從HTTP服務器端請求到信息和服務,目前的版本號是1.1 是無狀態協議,無狀態是指從客戶端發送HTTP請求到服務器,服務器接收到請求之后做出回應,這樣鏈接就關閉了,在服務器端不需要保留客戶端的相關信息。
二、協議過程
HTTP通訊機制是在一次完整的HTTP通訊過程中,客戶端和服務器之間建立連接分為以下幾個步驟。
1. 建立連接: 其中包括:域名解析,TCP三次握手。
域名解析:將HTTP請求中的域名轉化為IP地址,其中主要步驟有,以Chrome為例,訪問www.baidu.com
① 首先,Chrome會搜索瀏覽器自身的DNS緩存(緩存較少),看自身有沒有改域名的IP地址,如果有停止解析返回IP,如果沒有繼續解析。
注解:Chrome中的DNS可以通過在瀏覽器中輸入 chrome://net-internals/#dns 來進行查看瀏覽器DNS緩存。
② 如果在瀏覽器的自身的DNS緩存中沒有找到,那么Chrome會搜索操作系統自身的DNS緩存,如果找到就停止,沒有找到繼續解析。
注解:可以通過命令行 ipconfig /displaydns 來查看操作系統的DNS緩存。
③ 如果chrome在操作系統的DNS緩存中沒有找到,那么會嘗試讀取host(C:\Windows\System32\drivers\etc)文件,看看這里面有沒有對應的DNS地址
④ 如果host文件中沒有找到,那么chrome會發送一個DNS系統調用, 會首先向默認的DNS服務器發送域名解析(一般默認的是網絡運營商的,通過UDP協議向DNS的53端口發送請求),如果網絡運營商有該域名緩存,那么返回IP,如果沒有,該運營商的DNS會發起一個迭代DNS解析請求,首先找到根域名的IP地址,即com域的IP地址。運營商會繼續想com域發送域名解析請求,獲得baidu.com域的IP地址,進而獲得需要解析域名的IP地址(如果www.baidu.com 這么難訪問,那么就離退休不遠了)。
TCP三次握手:拿到域名的IP之后,client會以一個隨機端口向web服務器指定端口(默認為80端口,有時候也有用8080端口的)發送TCP鏈接請求。
2. 發送數據:
client與server建立連接之后,client向server端發送數據包其中數據包中包含以下信息
⑴ 請求方法 URI協議/版本
⑵ 請求頭(Request Header)
⑶ 請求正文
eg.
GET/index.jspHTTP/1.1 Accept:image/gif.image/jpeg,*/* Accept-Language:zh-cn Connection:Keep-Alive Host:localhost User-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0) Accept-Encoding:gzip,deflate username=jinqiao&password=1234
⑴ 請求方法 URI協議/版本
請求的第一行 GET/index.jsp HTTP/1.1
“GET” 代表請求方法,“/index.jsp”代表URI協議,“HTTP/1.1”代表協議和協議版本,其中HTTP1.1 支持了七種方法,GET,POST,HEAD,PUT,DELETE,TRACE,CONNECT,OPTIONS. 下面主要說一下GET與POST方法。
GET:默認的HTTP請求數據,只是對需要提交的信息進行了簡單的編碼,並將信息附加在URL地址之后 eg. Http://localhost/login.php?username=aa&password=1234 這樣會產生將用戶的信息暴露的危險。並且瀏覽器會對URL的長度進行限制,所以提交的信息也有限制。
POST:主要作用是向web提交表單信息,克服了GET的不安全和數據長度限制的缺點,在發送數據時POST不會將數據附加在URL之后,相對GET方法安全(推薦使用POST方法)。
⑵ 請求頭
請求第二行之后就是請求頭,其中包含了客戶端環境的相關信息,包含:瀏覽器所用語言,請求正文長度等。
⑶ 請求正文
請求頭結束之后有一個空行(空行表示請求頭結束,請求正文開始)
3. 返回數據:
server端接收到client端的請求之后,開始響應client端,返回數據包。其中數據包包含如下信息
⑴ 協議狀態版本代碼描述
⑵ 響應頭
⑶ 響應正文
eg.
1 HTTP/1.1 200 OK 2 Server:Apache Tomcat/5.0.12 3 Date:Mon,6Oct2003 13:23:42 GMT 4 Content-Length:112 5
6 <html>
7 <head>
8 ... 9 </body>
10 </html>
⑴ 協議狀態版本代碼描述
響應的第一行 “HTTP/1.1” 是協議版本, 200 OK 表示響應成功
HTTP應答碼也成狀態碼,反映了本次HTTP請求的狀態,其中主要分為以下幾種
1XX -信息類,表示收到了請求進一步處理中
2XX -成功類,表示用戶的請求被正確接收正,理解,處理。例如200 OK
3XX -重定向類,表示用戶請求沒有成功,客戶端需要采取進一步動作
4XX -客戶端錯誤,表示客戶端請求錯誤,其中404 NOT FOUNT 表示資源沒有找到
5XX -服務器端錯誤,表示服務器不能完成相對於的錯誤,一般是服務器內部錯誤。
⑵ 響應頭
與請求的類似
⑶ 響應正文
響應頭結束之后有一個空行,表示響應頭結束,響應正文開始。
4. 關閉連接:
通過TCP四次握手斷開連接。
TCP 四次握手過程
TCP是一個全雙工的連接, 所以斷開的時候需要兩個方向分開斷開, 原則:一個方向沒有數據流動時候發送FIN包斷開這個方向的連接。
關閉原則 : 先關閉寫通道,后關閉讀通道
【1】 客戶端發送FIN來斷開 客戶端C和服務器方向的連接(關閉客戶端向服務器的寫通道)
【2】 服務器端確認斷開連接 向客戶端發送確認消息(關閉客戶端向服務器的讀通道)
【3】 服務器端發送FIN來斷開 服務器和客戶端方向的連接(關閉服務器的向寫通道)
【4】 客戶端確認斷開連接,向服務器端確認(關閉服務器向客戶端的讀通道)
CLOSE_WAIT:
TCP的Close狀態出現在被動關閉方(不一定是服務器),出現的時間在接收到主動關閉方的FIN而自身未發送 ACK, 如果出現大量的 close-wait需要檢查服務器代碼.
TIME_WAIT:
TCP關閉的主動方在接受到FIN之后再等待2MSL(windows大概240S)后再關閉
原因
【1】防止IP通信不穩定,如果直接Close, 如果服務器沒有接收到客戶端的Close-Wait,再次向客戶端發送FIN, 此時客戶端已經關閉,則返回的是RST,服務端會把這個錯誤交到高層。
【2】防止原來的數據影響下次通訊, 如果主動方直接Close, 並且向服務器重新發送另外一個請求,雖然說端口不一定相同, 但是如果相同的話,原來的socket中滯留的數據,在建立連接之后發送到服
務端,這樣會造成數據混餚,所以TCP要等待 2MSL之后關閉連接。
經過千錘百煉出來的各種協議,每一處設計都有它的巧妙的體現!!!!!!!!!!!!