最近一直在研究如何讓asp.net實現上傳大文件的功能,因此都沒怎麼寫技術類的文章了。惋惜的是至今還沒研究出來,慚愧~~~。不過由於這樣,也瞭解了一下http消息請求的大體過程。我就先簡單介紹下,而後再來說如何利用Telnet來模擬Http請求。講得不對的地方還但願你們給我指出來。由於內容比較多,因此分紅兩部分來寫。
一、流程簡介
二、Telnet模擬HTTP請求
這篇咱們就來作一個簡單介紹。
先提個問題:當咱們在瀏覽器的地址欄中輸入"http://www.baidu.com/",而後按"回車",這以後發生了什麼事?這裏先不回答,你們接着往下看先。
咱們來分析一下:
·HTTP請求流程
首先,http屬於Tcp/Ip模型中的應用層協議,而兩個應用程序(咱們這裏指的就是瀏覽器與服務器)之間要進行互相通訊,首先得創建Tcp鏈接,而後瀏覽器才能向服務器發送請求信息,服務器在接受到請求信息後,返回相應的應答信息,瀏覽器接收到來自服務器的應答信息後,對這些數據進行解釋執行。
在http 1.0的版本中,瀏覽器的每次請求(也就是對每個頁面的訪問)都要求創建一次單獨的鏈接,在處理完每一次的請求後,就自動釋放鏈接。(這點咱們應該都有感受,好比咱們訪問一個頁面,當該頁面在瀏覽器中顯示出來的時候,咱們能夠拔掉網線,此時該頁面上的信息並不會丟失。)而當咱們請求的網頁文件中有不少圖片、音樂、電影等信息時,服務器返回的信息中並不直接包含圖片數據,而只是保存該圖片的連接,當瀏覽器進行解釋的時候,遇到圖片的url時,才向服務器發出對圖片的請求信息。可見若是一個網頁中包含多個圖片數據時,將會頻繁的與服務器創建鏈接,與釋放鏈接,這無疑會形成資源的浪費。html
http 1.0 請求模式
而http 1.1則能夠在一次鏈接中處理多個請求,而且多個請求能夠重疊進行,不須要等待一個請求結束後再發送下一個請求。web
創建鏈接的方式瀏覽器
HTTP支持2中創建鏈接的方式:非持久鏈接和持久鏈接(HTTP1.1默認的鏈接方式爲持久鏈接)。緩存
1) 非持久鏈接服務器
讓咱們查看一下非持久鏈接狀況下從服務器到客戶傳送一個Web頁面的步驟。假設該貝面由1個基本HTML文件和10個JPEG圖像構成,並且全部這些對象都存放在同一臺服務器主機中。再假設該基本HTML文件的URL爲:gpcuster.cnblogs.com/index.html。asp.net
下面是具體步騾:工具
1.HTTP客戶初始化一個與服務器主機gpcuster.cnblogs.com中的HTTP服務器的TCP鏈接。HTTP服務器使用默認端口號80監聽來自HTTP客戶的鏈接創建請求。2.HTTP客戶經由與TCP鏈接相關聯的本地套接字發出—個HTTP請求消息。這個消息中包含路徑名/somepath/index.html。3.HTTP服務器經由與TCP鏈接相關聯的本地套接字接收這個請求消息,再從服務器主機的內存或硬盤中取出對象/somepath/index.html,經由同一個套接字發出包含該對象的響應消息。post
4.HTTP服務器告知TCP關閉這個TCP鏈接(不過TCP要到客戶收到剛纔這個響應消息以後纔會真正終止這個鏈接)。網站
5.HTTP客戶經由同一個套接字接收這個響應消息。TCP鏈接隨後終止。該消息標明所封裝的對象是一個HTML文件。客戶從中取出這個文件,加以分析後發現其中有10個JPEG對象的引用。ui
6.給每個引用到的JPEG對象重複步騾1-4。
上述步驟之因此稱爲使用非持久鏈接,緣由是每次服務器發出一個對象後,相應的TCP鏈接就被關閉,也就是說每一個鏈接都沒有持續到可用於傳送其餘對象。每一個TCP鏈接只用於傳輸一個請求消息和一個響應消息。就上述例子而言,用戶每請求一次那個web頁面,就產生11個TCP鏈接。
2) 持久鏈接
非持久鏈接有些缺點。首先,客戶得爲每一個待請求的對象創建並維護一個新的鏈接。對於每一個這樣的鏈接,TCP得在客戶端和服務器端分配TCP緩衝區,並維持TCP變量。對於有可能同時爲來自數百個不一樣客戶的請求提供服務的web服務器來講,這會嚴重增長其負擔。其次,如前所述,每一個對象都有2個RTT的響應延長——一個RTT用於創建TCP鏈接,另—個RTT用於請求和接收對象。最後,每一個對象都遭受TCP緩啓動,由於每一個TCP鏈接都起始於緩啓動階段。不過並行TCP鏈接的使用可以部分減輕RTT延遲和緩啓動延遲的影響。
在持久鏈接狀況下,服務器在發出響應後讓TCP鏈接繼續打開着。同一對客戶/服務器之間的後續請求和響應能夠經過這個鏈接發送。整個Web頁面(上例中爲包含一個基本HTMLL文件和10個圖像的頁面)自不用說能夠經過單個持久TCP鏈接發送:甚至存放在同一個服務器中的多個web頁面也能夠經過單個持久TCP鏈接發送。一般,HTTP服務器在某個鏈接閒置一段特定時間後關閉它,而這段時間一般是能夠配置的。持久鏈接分爲不帶流水線(without pipelining)和帶流水線(with pipelining)兩個版本。若是是不帶流水線的版本,那麼客戶只在收到前一個請求的響應後才發出新的請求。這種狀況下,web頁面所引用的每一個對象(上例中的10個圖像)都經歷1個RTT的延遲,用於請求和接收該對象。與非持久鏈接2個RTT的延遲相比,不帶流水線的持久鏈接已有所改善,不過帶流水線的持久鏈接還能進一步下降響應延遲。不帶流水線版本的另外一個缺點是,服務器送出一個對象後開始等待下一個請求,而這個新請求卻不能立刻到達。這段時間服務器資源便閒置了。
HTTP/1.1的默認模式使用帶流水線的持久鏈接。這種狀況下,HTTP客戶每碰到一個引用就當即發出一個請求,於是HTTP客戶能夠一個接一個緊挨着發出各個引用對象的請求。服務器收到這些請求後,也能夠一個接一個緊挨着發出各個對象。若是全部的請求和響應都是緊挨着發送的,那麼全部引用到的對象一共只經歷1個RTT的延遲(而不是像不帶流水線的版本那樣,每一個引用到的對象都各有1個RTT的延遲)。另外,帶流水線的持久鏈接中服務器空等請求的時間比較少。與非持久鏈接相比,持久鏈接(不管是否帶流水線)除下降了1個RTT的響應延遲外,緩啓動延遲也比較小。其緣由在於既然各個對象使用同一個TCP鏈接,服務器發出第一個對象後就沒必要再以一開始的緩慢速率發送後續對象。相反,服務器能夠按照第一個對象發送完畢時的速率開始發送下一個對象。 ·