1、TCP/IP 協議介紹html
在介紹 HTTP 協議以前,先簡單說一下TCP/IP協議的相關內容。TCP/IP協議是分層的,從底層至應用層分別爲:物理層、鏈路層、網絡層、傳輸層和應用層,以下圖所示:web
從應用層至物理層,數據是一層層封裝,封裝的方式通常都是在原有數據的前面加一個數據控制頭,數據封裝格式以下:編程
其中,對於TCP傳輸協議,客戶端在於服務器創建鏈接前須要通過TCP三層握手,過程以下:windows
2、HTTP協議後端
2.1 簡介瀏覽器
超文本傳輸協議(Hypertext Transfer Protocol,簡稱HTTP)是應用層協議,自 1990 年起,HTTP 就已經被應用於 WWW 全球信息服務系統。
HTTP 是一種請求/響應式的協議。一個客戶機與服務器創建鏈接後,發送一個請求給服務器;服務器接到請求後,給予相應的響應信息。
HTTP 的初版本 HTTP/0.9是一種簡單的用於網絡間原始數據傳輸的協議;
HTTP/1.0由 RFC 1945 定義 ,在原 HTTP/0.9 的基礎上,有了進一步的改進,容許消息以類 MIME 信息格式存 在,包括請求/響應範式中的已傳輸數據和修飾符等方面的信息;
HTTP/1.1(RFC2616) 的要求更加嚴格以確保服務的可靠性,加強了在HTTP/1.0 沒有充分考慮到分層代理服務器、高速緩衝存儲器、持久鏈接需求或虛擬主機等方面的效能;
安全加強版的 HTTP (即S-HTTP或HTTPS),則是HTTP協議與安全套接口層(SSL)的結合,使HTTP的協議數據在傳輸過程當中更加安全。緩存
2.2 協議結構安全
HTTP協議格式也比較簡單,格式以下:服務器
2.3 HTTP 協議舉例cookie
下面是一個HTTP請求及響應的例子:
2.4 請求頭格式
a) 通用頭(general-header):
Cache-Control:客戶端但願服務端如何緩存本身的請求數據,如"Cache-Control: no-cache","Cache-Control: max-age=0";
Connection:客戶端是否但願與服務端之間保持長鏈接,如"Connection: close", "Connection: keep-alive";
Date:只有當請求方法爲POST或PUT方法時客戶端纔可能會有些字段;
Pragma:包含了客戶端一些特殊請求信息,如 "Pragma: no-cache" 客戶端但願代理或應用服務器不該緩存與該請求相關的結果數據;
Via:通常用在代理網關嚮應用服務器發送的請求頭中,代表該來自客戶端的請求通過了網關代理,
格式爲:"Via: 請求協議版本 網關標識 [其它信息] ",
如 :" Via: 1.1 webcache_250_199.hexun.com:80 (squid)"
b) 請求頭(request-header):
Accept: 代表客戶同端可接受的請求迴應的媒體類型範圍列表。星號「*」用於按範圍將類型分組,用「*/*」指示可接受所有類型;用「type/*」指示可接受 type類型的全部子類型,如「 Accept: image/gif, image/jpeg, */*」;
Accept-Charset:客戶端所能識別的字符集編碼格式,格式:「Accept-Charset: 字符集1[:權重],字符集2[:權重]」,如:「 Accept-Charset: iso-8859-5, unicode-1-1;q=0.8」;
Accept-Language:客戶端所能識別的語言,格式:「Accept-Language: 語言1[:權重],語言2[:權重]」,如:」 Accept-Language: zh, en;q=0.7」;
Host:客戶請求的主機域名或主機IP,格式:「Host: 域名或IP[:端口號]」,如:「Host: www.hexun.com:80「,請求行中如有HTTP/1.1則必須有該請求頭;
User-Agent:代表用戶所使用的瀏覽器標識,主要用於統計的目的;
Referer:指明該請求是從哪一個關聯鏈接而來;
Accept-Encoding:客戶端所能識別的編碼壓縮格式,如:「Accept-Encoding: gzip, deflate」;
If- Modified-Since:該字段與客戶端緩存相關,客戶端所訪問的URL自該指定日期以來在服務端是否被修改過,若是修改過則服務端返回新的修改後 的信息,若是未修改過則服務器返回304代表此請求所指URL不曾修改過,如:「If-Modified-Since: Fri, 2 Sep 2006 19:37:36 GMT」;
If-None-Match:該字段與客戶端緩存相關,客戶端發送URL請求的同時發送該字段及標識,如 果服務端的標識與客戶端的標識一致,則返回304代表此URL未修改過,若是不一致則服務端返回完整的數據信息,如:「If-None-Match: 0f0a893aad8c61:253, 0f0a893aad8c61:252, 0f0a893aad8c61:251」;
Cookie:爲擴展字段,存儲於客戶端,向同一域名的服務端發送屬於該域的cookie,如:「Cookie: MailUserName=whouse」;
c) 實體頭(entity-header): (此類頭存在時要求有數據體)
Content-Encoding:客戶端所能識別的編碼壓縮格式,如:「Content-Encoding: gzip, deflate」;
Content-Length:客戶端以POST方法上傳數據時數據體部分的內容長度,如:「 Content-Length: 24」;
Content- Type:客戶端發送的數據體的內容類型,如:「Content-Type: application/x-www-form-urlencoded」爲以普通的POST方法發送的數據;「Content-Type: multipart/form-data; boundary=---------------------------5169208281820」,則代表數據體由多部分組成,分隔符爲 「-----------------------------5169208281820」;
2.5)響應格式
a) 通用頭(general-header):
Cache- Control:服務端要求中間代理及客戶端如何緩存本身響應的數據,如「Cache-Control: no-cache」,如:「Cache-Control: private」 不但願被緩存,「Cache-Control: public」 能夠被緩存;
Connection:服務端是否但願與客戶端之間保持長鏈接,如「Connection: close」, 「Connection: keep-alive」;
Date:只有當請求方法爲POST或PUT方法時客戶端纔可能會有些字段;
Pragma:包含了服務端一些特殊響應信息,如 「Pragma: no-cache」 服務端但願代理或客戶端不該緩存結果數據;
Transfer-Encoding:服務端向客戶端傳輸數據所採用的傳輸模式(僅在HTTP1.1中出現),如:「Transfer-Encoding: chunked」,注:該字段的優先級要高於「Content-Length」 字段的優先級;
b)響應頭(response-header):
Accept-Ranges:代表服務端接收的數據單位,如:「Accept-Ranges: bytes」, ;
Location:服務端向客戶端返回此信息以使客戶端進行重定向,如:「Location: http://www.hexun.com」;
Server:服務端返回的用於標識本身的一些信息,如:「 Server: Microsoft-IIS/6.0」;
ETag:服務端返回的響應數據的標識字段,客戶端可根據此字段的值向服務器發送某URL是否更新的信息;
c)實體頭(entity-header): (此類頭存在時要求有數據體)
Content-Encoding:服務端所響應數據的編碼格式,如:「Content-Encoding: gzip」;
Content-Length:服務端所返回數據的數據體部分的內容長度,如:「 Content-Length: 24」;
Content-Type:服務端所返回的數據體的內容類型,如:「Content-Type: text/html; charset=gb2312」 ;
Set-Cookie:服務端返回給客戶端的cookie數據,如:「 Set-Cookie: ASP.NET_SessionId=icnh2ku2dqlmkciyobgvzl55; path=/」
2.6)服務器返回狀態碼
1xx:代表服務端接收了客戶端請求,客戶端繼續發送請求;
2xx:客戶端發送的請求被服務端成功接收併成功進行了處理;
3xx:服務端給客戶端返回用於重定向的信息;
4xx:客戶端的請求有非法內容;
5xx:服務端未能正常處理客戶端的請求而出現意外錯誤。
舉例:
「100」 ; 服務端但願客戶端繼續;
「200」 ; 服務端成功接收並處理了客戶端的請求;
「301」 ; 客戶端所請求的URL已經移走,須要客戶端重定向到其它的URL;
「304」 ; 客戶端所請求的URL未發生變化;
「400」 ; 客戶端請求錯誤;
「403」 ; 客戶端請求被服務端所禁止;
「404」 ; 客戶端所請求的URL在服務端不存在;
「500」 ; 服務端在處理客戶端請求時出現異常;
「501」 ; 服務端未實現客戶端請求的方法或內容;
「502」 ; 此爲中間代理返回給客戶端的出錯信息,代表服務端返回給代理時出錯;
「503」 ; 服務端因爲負載太高或其它錯誤而沒法正常響應客戶端請求;
「504」 ; 此爲中間代理返回給客戶端的出錯信息,代表代理鏈接服務端出現超時。
2.7)chunked 傳輸
編碼使用若干個Chunk組成,由一個標明長度爲0的chunk結束,每一個Chunk有兩部分組成,第一部分是該Chunk的長度(以十六進制表示)和 長度單位(通常不寫),第二部分就是指定長度的內容,每一個部分用CRLF隔開。在最後一個長度爲0的Chunk中的內容是稱爲footer的內容,是一些 沒有寫的頭部內容。另外,在HTTP頭裏必須含有:」 Transfer-Encoding: chunked」 通用頭字段。格式以下:
2.8)HTTP 請求方法
GET、POST、HEAD、CONNECT、PUT、DELETE、TRACE、OPTIONS
2.9)HTTP 斷點續傳
a)HTTP 請求頭
格式:Range: bytes={range_from}-{range_to}
該頭表示從後端 HTTP 服務器取數據,開始偏移位置爲 {range_from},結束偏移位置爲 {range_to},其中偏移位置下標從 0 開始;若是省略了 {range_to} 則表示從指定的開始位置 {range_from} 至數據結尾。
如:Range: bytes=1024-2048 其表示讀取從偏移位置 1024 至 2028 的數據,而 Range: bytes=1024- 則表示讀取從偏移位置 1024 至數據結尾的數據。
b)HTTP 響應頭
格式:Content-Range: bytes {range_from}-{range_to}/{total_length}
其中 {range_from} 和 {range_to} 分別表明當前從服務端返回的數據的起始偏移位置(下標從 0 開始),這是一個雙向閉區間範圍,而 total_length 則指定了整個數據的總長度,此時 HTTP 響應頭中的 Content-Length 若是存在,則其值表示當前返回的數據塊(由 {range_from} 和 {range_to} 指定的數據區間)的長度。該長度內的數據包括 {range_from} 和 {range_to} 兩個位置的數據。
3.0)舉例
a)GET請求
b)POST請求
c)經過HTTP代理髮送GET請求
d)POST方式上傳文件
e)CONNECT舉例
3.1)在終端以 telnet 方式測試
a)打開回顯功能(針對windows)
Windows 2000:進入DOS模式->輸入 telnet->set LOCAL_ECHO->退出:quit->telnet ip 80
Windows xp:進入DOS模式->輸入telnet->set local echo->open ip 80
b) 按HTTP協議格式輸入GET請求、HEAD請求、POST請求。
參考:
文章 《用C++實現相似於JAVA HttpServlet 的編程接口》 給出了 acl_cpp 庫中提供的 WEB 編程示例。
文章 《使用 acl_cpp 的 HttpServlet 類及 google 的 ctemplate 庫編寫 WEB 應用》 給出了使用 acl _cpp 的 WEB 庫及 google 的頁面模板庫的例子。
文章 《web 編程中實現文件上傳的服務端實例》 給出了使用 acl_cpp 的 WEB 庫實現處理 HTTP 文件上傳的例子。
文章 《使用 acl_cpp 的 HttpServlet 類及服務器框架編寫WEB服務器程序》 給出了使用 acl 服務器框架的 WEB 應用實例 。
文章 《使用 acl 庫開發一個 HTTP 下載客戶端》 給出了利用 acl 庫寫的 HTTP 下載客戶端。
文章 《使用 acl 較爲底層的 HTTP 協議庫寫 HTTP 下載客戶端舉例》 給出另外一種 HTTP 客戶端下載的例子。