標籤:
前言
最近一直在做C# winform用戶端項目,因為涉及到和伺服器互動,所以研究了一下C#的HTTP網路編程。
Http通訊是通過Http請求報文和Http應答報文來實現的。
由於我開發的是用戶端,所以主要工作就在於封裝Http請求報文,以及收到應答報文後解析資料。
Http請求報文是什麼樣的
如果你使用的是chrome瀏覽器,按F12就可以開啟偵錯模式。現在主流的瀏覽器應該都支援這個功能。隨便開啟一個網頁,觸發一個超連結請求,應該就能抓取到Http請求報文。
舉個例子,以下是一個Http請求報文的截取內容。
我們可以看到請求報文中有很多參數,這裡不一一詳解各個參數的意義。
C#中實現Http請求
我個人認為,發送Http請求報文主要有四個步驟:
1. 初始化HttpWebRequest(需要引用System.Net)
2. 封裝Http cookie
3. 封裝Http報文頭
4. 封裝請求內容,並將封裝好的請求報文用Stream類寫入流(需要引用System.IO)
5. 接收應答報文
接下來,我們一步一步來講解如何在C#中完成Http請求報文的封裝。
初始化HttpWebRequest
使用請求地址作為參數,初始化一個HttpWebRequest執行個體。
// 初始化HttpWebRequest
HttpWebRequest httpRequest = (HttpWebRequest)HttpWebRequest.Create(strRequestUri);
封裝Http cookie
首先,簡單說明一下Cookie。有時也用其複數形式Cookies,指某些網站為了辨別使用者身份、進行session跟蹤而儲存在使用者本地終端上的資料(通常經過加密)。本文為了樣本,就以比較簡單的形式展現。
在C#中,使用Cookie類來封裝cookie,以索引值對的形式儲存。
然後,將這個封裝好的cookie添加到CookieContainer容器中,最後填入HttpWebRequest。既然是容器,顧名思義,可以添加多個cookie。
// 封裝Cookie
Uri uri = new Uri(strRequestUri);
Cookie cookie = new Cookie("Name", strCookie); // 設定key、value形式的Cookie
CookieContainer cookies = new CookieContainer();
cookies.Add(uri, cookie);
httpRequest.CookieContainer = cookies;
封裝Http Header
根據自己要發送的請求報文類型來填充Http報文頭。
以下是一個簡單範例:
// 封裝Http Header
httpRequest.Method = "Post";
httpRequest.Referer = strReferer;
httpRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36";
httpRequest.Accept = "text/plain, */*; q=0.01";
httpRequest.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
httpRequest.Timeout = 1000 * 30;
httpRequest.KeepAlive = true;
填充Http content,並寫入流
首先,將要寫入的內容轉為byte數組(假設是常值內容)。將數組長度填入HttpWebRequest的ContentLength欄位。
通過GetRequestStream()擷取HttpWebRequest的請求流。使用這個流對象寫入數組內容。
最後,千萬不要忘記關閉流。本人在開發C#用戶端和Java伺服器互動過程中,就遇到這個問題。由於忘記關閉流,Java伺服器在解析請求報文時,總是提示不能識別流的結尾。
// 通過流寫入請求資料
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(strContent); // 編碼形式按照個人需求來設定
httpRequest.ContentLength = bytes.Length;
Stream requestStream = httpRequest.GetRequestStream();
requestStream.Write(bytes, 0, bytes.Length);
requestStream.Close(); // 不要忘記關閉流
獲得應答報文
通過流將請求報文發出去後,可以通過HttpWebRequest的GetResponse()方法來擷取HttpWebResponse。
// 獲得應答報文
HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse();
Stream responseStream = httpResponse.GetResponseStream();
StreamReader reader = new StreamReader(responseStream, System.Text.Encoding.UTF8);
string strResponse = reader.ReadToEnd();
reader.Close();
responseStream.Close();
至此,Http請求過程結束。大家有疑問的地方,歡迎和我探討。
過兩天,我再整理一下上傳檔案的 Http方法。
附上完整方法
public static void PackageHttpRequest(string strRequestUri, string strReferer, string strContent, string strCookie)
{
// 初始化HttpWebRequest
HttpWebRequest httpRequest = (HttpWebRequest)HttpWebRequest.Create(strRequestUri);
// 封裝Cookie
Uri uri = new Uri(strRequestUri);
Cookie cookie = new Cookie("Name", strCookie); // 設定key、value形式的Cookie
CookieContainer cookies = new CookieContainer();
cookies.Add(uri, cookie);
httpRequest.CookieContainer = cookies;
// 封裝Http Header
httpRequest.Method = "Post";
httpRequest.Referer = strReferer;
httpRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36";
httpRequest.Accept = "text/plain, */*; q=0.01";
httpRequest.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
httpRequest.Timeout = 1000 * 30;
httpRequest.KeepAlive = true;
// 通過流寫入請求資料
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(strContent); // 編碼形式按照個人需求來設定
httpRequest.ContentLength = bytes.Length;
Stream requestStream = httpRequest.GetRequestStream();
requestStream.Write(bytes, 0, bytes.Length);
requestStream.Close(); // 不要忘記關閉流
// 獲得應答報文
HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse();
Stream responseStream = httpResponse.GetResponseStream();
StreamReader reader = new StreamReader(responseStream, System.Text.Encoding.UTF8);
string strResponse = reader.ReadToEnd();
reader.Close();
responseStream.Close();
}View Code
[C#]發送HTTP請求