C# 操作http协议学习总结
生活随笔
收集整理的這篇文章主要介紹了
C# 操作http协议学习总结
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
C#中HttpWebRequest的用法詳解
http://www.jb51.net/article/57156.htm這篇文章主要介紹了C#中HttpWebRequest的用法,以實(shí)例的形式詳細(xì)敘述了HttpWebRequest類中GET與POST的用法,非常具有參考借鑒價(jià)值,需要的朋友可以參考下
HttpWebRequest類主要利用HTTP 協(xié)議和服務(wù)器交互,通常是通過 GET 和 POST 兩種方式來對(duì)數(shù)據(jù)進(jìn)行獲取和提交。下面對(duì)這兩種方式進(jìn)行一下說明:
GET 方式:
GET 方式通過在網(wǎng)絡(luò)地址附加參數(shù)來完成數(shù)據(jù)的提交,比如在地址 http://www.jb51.net/?hl=zh-CN 中,前面部分 http://www.jb51.net表示數(shù)據(jù)提交的網(wǎng)址,后面部分 hl=zh-CN 表示附加的參數(shù),其中 hl 表示一個(gè)鍵(key), zh-CN 表示這個(gè)鍵對(duì)應(yīng)的值(value)。
程序代碼如下: ?
復(fù)制代碼 代碼如下:HttpWebRequest req = (HttpWebRequest) HttpWebRequest.Create( "http://www.jb51.net?hl=zh-CN" );
req.Method = "GET";
using (WebResponse wr = req.GetResponse())
{
//在這里對(duì)接收到的頁面內(nèi)容進(jìn)行處理
}
使用 GET 方式提交中文數(shù)據(jù)。
GET 方式通過在網(wǎng)絡(luò)地址中附加參數(shù)來完成數(shù)據(jù)提交,對(duì)于中文的編碼,常用的有 gb2312 和 utf8 兩種。
用 gb2312 方式編碼訪問的程序代碼如下:
復(fù)制代碼 代碼如下:Encoding myEncoding = Encoding.GetEncoding("gb2312");
string address = "http://www.jb51.net/?" + HttpUtility.UrlEncode("參數(shù)一", myEncoding) + "=" + HttpUtility.UrlEncode("值一", myEncoding);
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(address);
req.Method = "GET";
using (WebResponse wr = req.GetResponse())
{
//在這里對(duì)接收到的頁面內(nèi)容進(jìn)行處理
}
在上面的程序代碼中,我們以 GET 方式訪問了網(wǎng)址 http://www.jb51.net ,傳遞了參數(shù)“參數(shù)一=值一”,由于無法告知對(duì)方提交數(shù)據(jù)的編碼類型,所以編碼方式要以對(duì)方的網(wǎng)站為標(biāo)準(zhǔn)。
?
POST 方式:
POST 方式通過在頁面內(nèi)容中填寫參數(shù)的方法來完成數(shù)據(jù)的提交,參數(shù)的格式和 GET 方式一樣,是類似于 hl=zh-CN&newwindow=1 這樣的結(jié)構(gòu)。
程序代碼如下:
復(fù)制代碼 代碼如下:string param = "hl=zh-CN&newwindow=1";
byte[] bs = Encoding.ASCII.GetBytes(param);
HttpWebRequest req = (HttpWebRequest) HttpWebRequest.Create( "http://www.jb51.net/" );
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
req.ContentLength = bs.Length;
using (Stream reqStream = req.GetRequestStream())
{
? ?reqStream.Write(bs, 0, bs.Length);
}
using (WebResponse wr = req.GetResponse())
{
? ?//在這里對(duì)接收到的頁面內(nèi)容進(jìn)行處理
}
在上面的代碼中,我們?cè)L問了 http://www.jb51.net 的網(wǎng)址,分別以 GET 和 POST 方式提交了數(shù)據(jù),并接收了返回的頁面內(nèi)容。然而,如果提交的參數(shù)中含有中文,那么這樣的處理是不夠的,需要對(duì)其進(jìn)行編碼,讓對(duì)方網(wǎng)站能夠識(shí)別。 ?
使用 POST 方式提交中文數(shù)據(jù)
POST 方式通過在頁面內(nèi)容中填寫參數(shù)的方法來完成數(shù)據(jù)的提交,由于提交的參數(shù)中可以說明使用的編碼方式,所以理論上能獲得更大的兼容性。
用 gb2312 方式編碼訪問的程序代碼如下: ?
復(fù)制代碼 代碼如下:Encoding myEncoding = Encoding.GetEncoding("gb2312");
string param = HttpUtility.UrlEncode("參數(shù)一", myEncoding) + "=" + HttpUtility.UrlEncode("值一", myEncoding) + "&" + HttpUtility.UrlEncode("參數(shù)二", myEncoding) + "=" + HttpUtility.UrlEncode("值二", myEncoding);
byte[] postBytes = Encoding.ASCII.GetBytes(param);
HttpWebRequest req = (HttpWebRequest) HttpWebRequest.Create( "http://www.jb51.net/" );
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded;charset=gb2312";
req.ContentLength = postBytes.Length;
using (Stream reqStream = req.GetRequestStream())
{
? ?reqStream.Write(bs, 0, bs.Length);
}
using (WebResponse wr = req.GetResponse())
{
? ?//在這里對(duì)接收到的頁面內(nèi)容進(jìn)行處理
}
從上面的代碼可以看出, POST 中文數(shù)據(jù)的時(shí)候,先使用 UrlEncode 方法將中文字符轉(zhuǎn)換為編碼后的 ASCII 碼,然后提交到服務(wù)器,提交的時(shí)候可以說明編碼的方式,用來使對(duì)方服務(wù)器能夠正確的解析。 ?
用C#語言寫的關(guān)于HttpWebRequest 類的使用方法
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
namespace HttpWeb
{
? ? /// <summary>?
? ? /// ?Http操作類?
? ? /// </summary>?
? ? public static class httptest
? ? {
? ? ? ? /// <summary>?
? ? ? ? /// ?獲取網(wǎng)址HTML?
? ? ? ? /// </summary>?
? ? ? ? /// <param name="URL">網(wǎng)址 </param>?
? ? ? ? /// <returns> </returns>?
? ? ? ? public static string GetHtml(string URL)
? ? ? ? {
? ? ? ? ? ? WebRequest wrt;
? ? ? ? ? ? wrt = WebRequest.Create(URL);
? ? ? ? ? ? wrt.Credentials = CredentialCache.DefaultCredentials;
? ? ? ? ? ? WebResponse wrp;
? ? ? ? ? ? wrp = wrt.GetResponse();
? ? ? ? ? ? string reader = new StreamReader(wrp.GetResponseStream(), Encoding.GetEncoding("gb2312")).ReadToEnd();
? ? ? ? ? ? try
? ? ? ? ? ? {
? ? ? ? ? ? ? ? wrt.GetResponse().Close();
? ? ? ? ? ? }
? ? ? ? ? ? catch (WebException ex)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? throw ex;
? ? ? ? ? ? }
? ? ? ? ? ? return reader;
? ? ? ? }
? ? ? ? /// <summary>?
? ? ? ? /// 獲取網(wǎng)站cookie?
? ? ? ? /// </summary>?
? ? ? ? /// <param name="URL">網(wǎng)址 </param>?
? ? ? ? /// <param name="cookie">cookie </param>?
? ? ? ? /// <returns> </returns>?
? ? ? ? public static string GetHtml(string URL, out string cookie)
? ? ? ? {
? ? ? ? ? ? WebRequest wrt;
? ? ? ? ? ? wrt = WebRequest.Create(URL);
? ? ? ? ? ? wrt.Credentials = CredentialCache.DefaultCredentials;
? ? ? ? ? ? WebResponse wrp;
? ? ? ? ? ? wrp = wrt.GetResponse();
? ? ? ? ? ? string html = new StreamReader(wrp.GetResponseStream(), Encoding.GetEncoding("gb2312")).ReadToEnd();
? ? ? ? ? ? try
? ? ? ? ? ? {
? ? ? ? ? ? ? ? wrt.GetResponse().Close();
? ? ? ? ? ? }
? ? ? ? ? ? catch (WebException ex)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? throw ex;
? ? ? ? ? ? }
? ? ? ? ? ? cookie = wrp.Headers.Get("Set-Cookie");
? ? ? ? ? ? return html;
? ? ? ? }
? ? ? ? public static string GetHtml(string URL, string postData, string cookie, out string header, string server)
? ? ? ? {
? ? ? ? ? ? return GetHtml(server, URL, postData, cookie, out header);
? ? ? ? }
? ? ? ? public static string GetHtml(string server, string URL, string postData, string cookie, out string header)
? ? ? ? {
? ? ? ? ? ? byte[] byteRequest = Encoding.GetEncoding("gb2312").GetBytes(postData);
? ? ? ? ? ? return GetHtml(server, URL, byteRequest, cookie, out header);
? ? ? ? }
? ? ? ? public static string GetHtml(string server, string URL, byte[] byteRequest, string cookie, out string header)
? ? ? ? {
? ? ? ? ? ? byte[] bytes = GetHtmlByBytes(server, URL, byteRequest, cookie, out header);
? ? ? ? ? ? Stream getStream = new MemoryStream(bytes);
? ? ? ? ? ? StreamReader streamReader = new StreamReader(getStream, Encoding.GetEncoding("gb2312"));
? ? ? ? ? ? string getString = streamReader.ReadToEnd();
? ? ? ? ? ? streamReader.Close();
? ? ? ? ? ? getStream.Close();
? ? ? ? ? ? return getString;
? ? ? ? }
? ? ? ? /// <summary>?
? ? ? ? /// Post模式瀏覽?
? ? ? ? /// </summary>?
? ? ? ? /// <param name="server">服務(wù)器地址 </param>?
? ? ? ? /// <param name="URL">網(wǎng)址 </param>?
? ? ? ? /// <param name="byteRequest">流 </param>?
? ? ? ? /// <param name="cookie">cookie </param>?
? ? ? ? /// <param name="header">句柄 </param>?
? ? ? ? /// <returns> </returns>?
? ? ? ? public static byte[] GetHtmlByBytes(string server, string URL, byte[] byteRequest, string cookie, out string header)
? ? ? ? {
? ? ? ? ? ? long contentLength;
? ? ? ? ? ? HttpWebRequest httpWebRequest;
? ? ? ? ? ? HttpWebResponse webResponse;
? ? ? ? ? ? Stream getStream;
? ? ? ? ? ? httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(URL);
? ? ? ? ? ? CookieContainer co = new CookieContainer();
? ? ? ? ? ? co.SetCookies(new Uri(server), cookie);
? ? ? ? ? ? httpWebRequest.CookieContainer = co;
? ? ? ? ? ? httpWebRequest.ContentType = "application/x-www-form-urlencoded";
? ? ? ? ? ? httpWebRequest.Accept =
? ? ? ? ? ? ? ? "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*";
? ? ? ? ? ? httpWebRequest.Referer = server;
? ? ? ? ? ? httpWebRequest.UserAgent =
? ? ? ? ? ? ? ? "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Maxthon; .NET CLR 1.1.4322)";
? ? ? ? ? ? httpWebRequest.Method = "Post";
? ? ? ? ? ? httpWebRequest.ContentLength = byteRequest.Length;
? ? ? ? ? ? Stream stream;
? ? ? ? ? ? stream = httpWebRequest.GetRequestStream();
? ? ? ? ? ? stream.Write(byteRequest, 0, byteRequest.Length);
? ? ? ? ? ? stream.Close();
? ? ? ? ? ? webResponse = (HttpWebResponse)httpWebRequest.GetResponse();
? ? ? ? ? ? header = webResponse.Headers.ToString();
? ? ? ? ? ? getStream = webResponse.GetResponseStream();
? ? ? ? ? ? contentLength = webResponse.ContentLength;
? ? ? ? ? ? byte[] outBytes = new byte[contentLength];
? ? ? ? ? ? outBytes = ReadFully(getStream);
? ? ? ? ? ? getStream.Close();
? ? ? ? ? ? return outBytes;
? ? ? ? }
? ? ? ? public static byte[] ReadFully(Stream stream)
? ? ? ? {
? ? ? ? ? ? byte[] buffer = new byte[128];
? ? ? ? ? ? using (MemoryStream ms = new MemoryStream())
? ? ? ? ? ? {
? ? ? ? ? ? ? ? while (true)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? int read = stream.Read(buffer, 0, buffer.Length);
? ? ? ? ? ? ? ? ? ? if (read <= 0)
? ? ? ? ? ? ? ? ? ? ? ? return ms.ToArray();
? ? ? ? ? ? ? ? ? ? ms.Write(buffer, 0, read);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? /// <summary>?
? ? ? ? /// Get模式?
? ? ? ? /// </summary>?
? ? ? ? /// <param name="URL">網(wǎng)址 </param>?
? ? ? ? /// <param name="cookie">cookies </param>?
? ? ? ? /// <param name="header">句柄 </param>?
? ? ? ? /// <param name="server">服務(wù)器 </param>?
? ? ? ? /// <param name="val">服務(wù)器 </param>?
? ? ? ? /// <returns> </returns>?
? ? ? ? public static string GetHtml(string URL, string cookie, out string header, string server)
? ? ? ? {
? ? ? ? ? ? return GetHtml(URL, cookie, out header, server, "");
? ? ? ? }
? ? ? ? /// <summary>?
? ? ? ? /// Get模式瀏覽?
? ? ? ? /// </summary>?
? ? ? ? /// <param name="URL">Get網(wǎng)址 </param>?
? ? ? ? /// <param name="cookie">cookie </param>?
? ? ? ? /// <param name="header">句柄 </param>?
? ? ? ? /// <param name="server">服務(wù)器地址 </param>?
? ? ? ? /// <param name="val"> </param>?
? ? ? ? /// <returns> </returns>?
? ? ? ? public static string GetHtml(string URL, string cookie, out string header, string server, string val)
? ? ? ? {
? ? ? ? ? ? HttpWebRequest httpWebRequest;
? ? ? ? ? ? HttpWebResponse webResponse;
? ? ? ? ? ? Stream getStream;
? ? ? ? ? ? StreamReader streamReader;
? ? ? ? ? ? string getString = "";
? ? ? ? ? ? httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(URL);
? ? ? ? ? ? httpWebRequest.Accept = "*/*";
? ? ? ? ? ? httpWebRequest.Referer = server;
? ? ? ? ? ? CookieContainer co = new CookieContainer();
? ? ? ? ? ? co.SetCookies(new Uri(server), cookie);
? ? ? ? ? ? httpWebRequest.CookieContainer = co;
? ? ? ? ? ? httpWebRequest.UserAgent =
? ? ? ? ? ? ? ? "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Maxthon; .NET CLR 1.1.4322)";
? ? ? ? ? ? httpWebRequest.Method = "GET";
? ? ? ? ? ? webResponse = (HttpWebResponse)httpWebRequest.GetResponse();
? ? ? ? ? ? header = webResponse.Headers.ToString();
? ? ? ? ? ? getStream = webResponse.GetResponseStream();
? ? ? ? ? ? streamReader = new StreamReader(getStream, Encoding.GetEncoding("gb2312"));
? ? ? ? ? ? getString = streamReader.ReadToEnd();
? ? ? ? ? ? streamReader.Close();
? ? ? ? ? ? getStream.Close();
? ? ? ? ? ? return getString;
? ? ? ? }
? ?}
}
========
C# 利用HttpListener監(jiān)聽處理Http請(qǐng)求
http://blog.sina.com.cn/s/blog_6f3ff2c90101wwh5.htmlusing System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Xml.Serialization;
using System.Threading;
using System.Web;
namespace ConsoleApplication3
{
? ? class Program
? ? {
? ? ? ? static void Main(string[] args)
? ? ? ? {
? ? ? ? ? ? try
? ? ? ? ? ? {
? ? ? ? ? ? ? ? HttpListener listerner = new HttpListener();
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? for (; true; )
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? try
? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? Console.Write("請(qǐng)輸入服務(wù)器IP地址:");
? ? ? ? ? ? ? ? ? ? ? ? ? ? string ip = Console.ReadLine();
? ? ? ? ? ? ? ? ? ? ? ? ? ? listerner.AuthenticationSchemes = AuthenticationSchemes.Anonymous;//指定身份驗(yàn)證 Anonymous匿名訪問
? ? ? ? ? ? ? ? ? ? ? ? ? ? listerner.Prefixes.Add("http://" + ip + ":1500/AnsweringMachineService/");
? ? ? ? ? ? ? ? ? ? ? ? ? ? // listerner.Prefixes.Add("http://localhost/web/");
? ? ? ? ? ? ? ? ? ? ? ? ? ? listerner.Start();
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? catch (Exception e)
? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? Console.WriteLine("未能成功連接服務(wù)器.....");
? ? ? ? ? ? ? ? ? ? ? ? ? ? listerner = new HttpListener();
? ? ? ? ? ? ? ? ? ? ? ? ? ? continue;
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? Console.WriteLine("服務(wù)器啟動(dòng)成功.......");
? ? ? ? ? ? ? ? ? ? int maxThreadNum, portThreadNum;
? ? ? ? ? ? ? ? ? ? //線程池
? ? ? ? ? ? ? ? ? ? int minThreadNum;
? ? ? ? ? ? ? ? ? ? ThreadPool.GetMaxThreads(out maxThreadNum, out portThreadNum);
? ? ? ? ? ? ? ? ? ? ThreadPool.GetMinThreads(out minThreadNum, out portThreadNum);
? ? ? ? ? ? ? ? ? ? Console.WriteLine("最大線程數(shù):{0}", maxThreadNum);
? ? ? ? ? ? ? ? ? ? Console.WriteLine("最小空閑線程數(shù):{0}", minThreadNum);
? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? //ThreadPool.QueueUserWorkItem(new WaitCallback(TaskProc1), x);
? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? ? Console.WriteLine("\n\n等待客戶連接中。。。。");
? ? ? ? ? ? ? ? ? ? while (true)
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? //等待請(qǐng)求連接
? ? ? ? ? ? ? ? ? ? ? ? //沒有請(qǐng)求則GetContext處于阻塞狀態(tài)
? ? ? ? ? ? ? ? ? ? ? ? HttpListenerContext ctx = listerner.GetContext();
? ? ? ? ? ? ? ? ? ? ? ? ThreadPool.QueueUserWorkItem(new WaitCallback(TaskProc), ctx);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? con.Close();
? ? ? ? ? ? ? ? ? ? listerner.Stop();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? catch (Exception e)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? Console.WriteLine(e.Message);
? ? ? ? ? ? ? ? Console.Write("Press any key to continue . . . ");
? ? ? ? ? ? ? ? Console.ReadKey( );
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? static void TaskProc(object o)
? ? ? ? {
? ? ? ? ? ? HttpListenerContext ctx = (HttpListenerContext)o;
? ? ? ? ? ? ctx.Response.StatusCode = 200;//設(shè)置返回給客服端http狀態(tài)代碼
? ? ? ?
? ? ? ? ? ? string type = ctx.Request.QueryString["type"];
? ? ? ? ? ? string userId = ctx.Request.QueryString["userId"];
? ? ? ? ? ? string password = ctx.Request.QueryString["password"];
? ? ? ? ? ? string filename = Path.GetFileName(ctx.Request.RawUrl);
? ? ? ? ? ? string userName = HttpUtility.ParseQueryString(filename).Get("userName");//避免中文亂碼
? ? //進(jìn)行處理
? ? ? ? ? ??
? ? ? ? ? ? //使用Writer輸出http響應(yīng)代碼
? ? ? ? ? ? using (StreamWriter writer = new StreamWriter(ctx.Response.OutputStream))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? writer.Write(“處理結(jié)果”);
? ? ? ? ? ? ? ? writer.Close();
? ? ? ? ? ? ? ? ctx.Response.Close();
? ? ? ? ? ? }
? ? ? ? }
? ? }
}
Android客戶端:
public static void Register(final Handler handler, final Context context,
final String userId, final String userName,final int groupId, final String password){
new Thread(new Runnable(){
? ? ? ?public void run() {
? ? ? ? if(!CommonTools.checkNetwork(context)){
? ? ? ? Message msg = new Message();
? ? ? ? msg.what = Signal.NETWORK_ERR;
? ? ? ? handler.sendMessage(msg);
? ? ? ? return;
? ? ? ? }
? ? ? ?
? ? ? ? try { ?
? ? ? ? String content = "";
? ? ? ? String tmp ? = ? java.net.URLEncoder.encode(userName, ? "utf-8"); ? //防止中文亂碼
? ? ? ? URL url = new URL(URL+"?type=Register&userId="+userId+"&password="+password+"&groupId="+groupId+"&userName="+tmp); ??
? ? ? ? ? ? ? ?// HttpURLConnection ??
? ? ? ? ? ? ? ?HttpURLConnection httpconn = (HttpURLConnection) url.openConnection(); ??
? ? ?
? ? ? ? ? ? ? ?if (httpconn.getResponseCode() == HttpURLConnection.HTTP_OK) { ??
? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ?InputStreamReader isr = new InputStreamReader(httpconn.getInputStream(), "utf-8"); ??
? ? ? ? ? ? ? ? ? ?int i; ??
? ? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? ?// read ??
? ? ? ? ? ? ? ? ? ?while ((i = isr.read()) != -1) { ??
? ? ? ? ? ? ? ? ? ? ? ?content = content + (char) i; ??
? ? ? ? ? ? ? ? ? ?} ??
? ? ? ? ? ? ? ? ? ?isr.close(); ? ??
? ? ? ? ? ? ? ?} ??
? ? ? ? ? ? ? ?//disconnect ??
? ? ? ? ? ? ? ?httpconn.disconnect(); ??
? ? } catch (Exception e) {
? ? e.printStackTrace();
? ? }
? ? ? ?}//run
}).start();//thread
}
注意:
1.中文亂碼問題
? ?在客戶端采用如下形式
? ?String tmp ? = ? java.net.URLEncoder.encode(userName, ? "utf-8"); ? //防止中文亂碼
? ?服務(wù)器端
? ?string filename = Path.GetFileName(ctx.Request.RawUrl);
? ?string userName = HttpUtility.ParseQueryString(filename).Get("userName");//避免中文亂碼
?
? ?服務(wù)器端需要引入: using System.Web;
? ?此時(shí)可能提示找不到庫,則在項(xiàng)目右鍵添加引用 找到 System.Web.dll勾選即可
2.[System.Net.HttpListenerException] = {"拒絕訪問。"}問題
? ?如果是win7或者win8,在cmd.exe上右鍵,以管理員身份運(yùn)行,然后執(zhí)行下面的命令
? ?netsh http add urlacl url=http://本機(jī)IP:1500/ user=用戶名(如Administrator)
? ?
3.記得關(guān)閉防火墻,或者只開放指定端口,步驟如下:
? ? ? ? step1、點(diǎn)擊控制面板
step2、選擇windows防火墻,點(diǎn)擊高級(jí)設(shè)置
step3、在彈出的“高級(jí)安全windows防火墻”點(diǎn)擊“入站規(guī)則”,在右側(cè)“操作”欄點(diǎn)擊“入站規(guī)則”下的“新建規(guī)則…”,此時(shí)會(huì)彈出一個(gè)窗口讓你設(shè)置。剩下的就非常傻瓜化了。
step4、彈出“新建入站規(guī)則向?qū)А?規(guī)則類型-選中“端口”,點(diǎn)擊下一步。選擇規(guī)則應(yīng)用的協(xié)議“TCP/UDP”如果是TCP你就選擇TCP,UDP就選擇UDP。再勾選“特定本地端口”在文本框輸入您想開放的端口號(hào)(例如1521)。
step5、點(diǎn)擊下一步,到“連接符合指定條件時(shí)應(yīng)該進(jìn)行什么操作?”選擇“允許連接”。點(diǎn)擊下一步到“配置文件”何時(shí)應(yīng)用該規(guī)則,勾選“域”、“專用”、“公用”點(diǎn)擊下一步。
step6、配置規(guī)則名稱,隨便輸入你自己認(rèn)為好記的規(guī)則名稱即可。
========
C# 中使用System.Net.Http.HttpClient 模擬登錄博客園 (GET/POST)
http://www.tuicool.com/articles/rmiqYz主題 HttpComponents C#
一、 System.Net.Http .HttpClient簡介
System.Net.Http 是微軟.net4.5中推出的HTTP 應(yīng)用程序的編程接口, 微軟稱之為“現(xiàn)代化的 HTTP 編程接口”, 主要提供如下內(nèi)容:
1. 用戶通過 HTTP 使用現(xiàn)代化的 Web Service 的客戶端組件;
2. 能夠同時(shí)在客戶端與服務(wù)端同時(shí)使用的 HTTP 組件(比如處理 HTTP 標(biāo)頭和消息), 為客戶端和服務(wù)端提供一致的編程模型。
個(gè)人看來是抄襲 apache http client ,目前網(wǎng)上用的人好像不多, 個(gè)人認(rèn)為使用httpclient最大的好處是:不用自己管理cookie,只要負(fù)責(zé)寫好請(qǐng)求即可。
由于網(wǎng)上資料不多,這里借登錄博客園網(wǎng)站做個(gè)簡單的總結(jié)其get和post請(qǐng)求的用法。
查看微軟的api可以發(fā)現(xiàn)其屬性方法: http://msdn.microsoft.com/zh-cn/library/system.net.http.httpclient.aspx
由其api可以看出如果想 設(shè)置請(qǐng)求頭 只需要在 DefaultRequestHeaders 里進(jìn)行設(shè)置
創(chuàng)建httpcliet可以直接new HttpClient()
發(fā)送請(qǐng)求 可以按發(fā)送方式分別調(diào)用其方法,如 get調(diào)用 GetAsync(Uri) , post調(diào)用 PostAsync(Uri, HttpContent) ,其它依此類推。。。
二、實(shí)例(模擬post登錄博客園)
首先,需要說明的是, 本實(shí)例環(huán)境是win7 64位+vs 2013+ .net 4.5框架。
1.使用vs2013新建一個(gè)控制臺(tái)程序,或者窗體程序,如下圖所示:
2.必須引入System.Net.Http框架,否則將不能使用httpclient
3.實(shí)現(xiàn)代碼
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace ClassLibrary1
{
public class Class1
{
private static String dir = @"C:\work\";
/// <summary>
/// 寫文件到本地
/// </summary>
/// <param name="fileName"></param>
/// <param name="html"></param>
public static void Write(string fileName, string html)
{
try
{
FileStream fs = new FileStream(dir + fileName, FileMode.Create);
StreamWriter sw = new StreamWriter(fs, Encoding.Default);
sw.Write(html);
sw.Close();
fs.Close();
}catch(Exception ex){
Console.WriteLine(ex.StackTrace);
}
??
}
/// <summary>
/// 寫文件到本地
/// </summary>
/// <param name="fileName"></param>
/// <param name="html"></param>
public static void Write(string fileName, byte[] html)
{
try
{
File.WriteAllBytes(dir + fileName, html);
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
}
}
/// <summary>
/// 登錄博客園
/// </summary>
public static void LoginCnblogs()
{
HttpClient httpClient = new HttpClient();
httpClient.MaxResponseContentBufferSize = 256000;
httpClient.DefaultRequestHeaders.Add("user-agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.143 Safari/537.36");
String url = "http://passport.cnblogs.com/login.aspx";
HttpResponseMessage response = httpClient.GetAsync(new Uri(url)).Result;
String result = response.Content.ReadAsStringAsync().Result;
String username = "hi_amos";
String password = "密碼";
do
{
String __EVENTVALIDATION = new Regex("id=\"__EVENTVALIDATION\" value=\"(.*?)\"").Match(result).Groups[1].Value;
String __VIEWSTATE = new Regex("id=\"__VIEWSTATE\" value=\"(.*?)\"").Match(result).Groups[1].Value;
String LBD_VCID_c_login_logincaptcha = new Regex("id=\"LBD_VCID_c_login_logincaptcha\" value=\"(.*?)\"").Match(result).Groups[1].Value;
//圖片驗(yàn)證碼
url = "http://passport.cnblogs.com" + new Regex("id=\"c_login_logincaptcha_CaptchaImage\" src=\"(.*?)\"").Match(result).Groups[1].Value;
response = httpClient.GetAsync(new Uri(url)).Result;
Write("amosli.png", response.Content.ReadAsByteArrayAsync().Result);
Console.WriteLine("輸入圖片驗(yàn)證碼:");
String imgCode = "wupve";//驗(yàn)證碼寫到本地了,需要手動(dòng)填寫
imgCode = ?Console.ReadLine();
//開始登錄
url = "http://passport.cnblogs.com/login.aspx";
List<KeyValuePair<String, String>> paramList = new List<KeyValuePair<String, String>>();
paramList.Add(new KeyValuePair<string, string>("__EVENTTARGET", ""));
paramList.Add(new KeyValuePair<string, string>("__EVENTARGUMENT", ""));
paramList.Add(new KeyValuePair<string, string>("__VIEWSTATE", __VIEWSTATE));
paramList.Add(new KeyValuePair<string, string>("__EVENTVALIDATION", __EVENTVALIDATION));
paramList.Add(new KeyValuePair<string, string>("tbUserName", username));
paramList.Add(new KeyValuePair<string, string>("tbPassword", password));
paramList.Add(new KeyValuePair<string, string>("LBD_VCID_c_login_logincaptcha", LBD_VCID_c_login_logincaptcha));
paramList.Add(new KeyValuePair<string, string>("LBD_BackWorkaround_c_login_logincaptcha", "1"));
paramList.Add(new KeyValuePair<string, string>("CaptchaCodeTextBox", imgCode));
paramList.Add(new KeyValuePair<string, string>("btnLogin", "登 ?錄"));
paramList.Add(new KeyValuePair<string, string>("txtReturnUrl", "http://home.cnblogs.com/"));
response = httpClient.PostAsync(new Uri(url), new FormUrlEncodedContent(paramList)).Result;
result = response.Content.ReadAsStringAsync().Result;
Write("myCnblogs.html",result);
} while (result.Contains("驗(yàn)證碼錯(cuò)誤,麻煩您重新輸入"));
Console.WriteLine("登錄成功!");
//用完要記得釋放
httpClient.Dispose();
}
public static void Main()
{
?LoginCnblogs();
}
}
代碼分析:
首先,從Main函數(shù)開始,調(diào)用LoginCnblogs方法;
其次,使用GET方法:
HttpResponseMessage response = httpClient.GetAsync(new Uri(url)).Result;
?String result = response.Content.ReadAsStringAsync().Result;
再者,使用POST方法:
? List<KeyValuePair<String, String>> paramList = new List<KeyValuePair<String, String>>();
? ? ? ? ? ? ? ? paramList.Add(new KeyValuePair<string, string>("__EVENTTARGET", ""));
? ....
? ? ? ? ? ? ? ? response = httpClient.PostAsync(new Uri(url), new FormUrlEncodedContent(paramList)).Result;
? ? ? ? ? ? ? ? result = response.Content.ReadAsStringAsync().Result;
最后, 注意其返回值可以是string,也可以是byte[],和stream的方式,這里看你需要什么吧。
4.登錄成功后的截圖
1).使用瀏覽器登錄后的截圖:
2).使用Httpcliet登錄后的截圖:
總結(jié),可以發(fā)現(xiàn)C#中HttpClient的用法和Java中非常相似,所以,說其抄襲確實(shí)不為過。
========
在C#用HttpWebRequest中發(fā)送GET/HTTP/HTTPS請(qǐng)求
http://zhoufoxcn.blog.51cto.com/792419/561934/?這個(gè)需求來自于我最近練手的一個(gè)項(xiàng)目,在項(xiàng)目中我需要將一些自己發(fā)表的和收藏整理的網(wǎng)文集中到一個(gè)地方存放,如果全部采用手工操作工作量大而且繁瑣,因此周公決定利用C#來實(shí)現(xiàn)。在很多地方都需要驗(yàn)證用戶身份才可以進(jìn)行下一步操作,這就免不了POST請(qǐng)求來登錄,在實(shí)際過程中發(fā)現(xiàn)有些網(wǎng)站登錄是HTTPS形式的,在解決過程中遇到了一些小問題,現(xiàn)在跟大家分享。
?通用輔助類
?下面是我編寫的一個(gè)輔助類,在這個(gè)類中采用了HttpWebRequest中發(fā)送GET/HTTP/HTTPS請(qǐng)求,因?yàn)橛械臅r(shí)候需要獲取認(rèn)證信息(如Cookie),所以返回的是HttpWebResponse對(duì)象,有了返回的HttpWebResponse實(shí)例,可以獲取登錄過程中返回的會(huì)話信息,也可以獲取響應(yīng)流。
?代碼如下:
?
using System; ?
using System.Collections.Generic; ?
using System.Linq; ?
using System.Text; ?
using System.Net.Security; ?
using System.Security.Cryptography.X509Certificates; ?
using System.DirectoryServices.Protocols; ?
using System.ServiceModel.Security; ?
using System.Net; ?
using System.IO; ?
using System.IO.Compression; ?
using System.Text.RegularExpressions; ?
/* ? ?
?* 作者:周公(zhoufoxcn) ? ?
?* 日期:2011-05-08 ? ?
?* 原文出處:http://blog.csdn.net/zhoufoxcn 或http://zhoufoxcn.blog.51cto.com ? ?
?* 版權(quán)說明:本文可以在保留原文出處的情況下使用于非商業(yè)用途,周公對(duì)此不作任何擔(dān)保或承諾。 ? ?
?* */?
namespace BaiduCang ?
{ ?
? ? /// <summary> ?
? ? /// 有關(guān)HTTP請(qǐng)求的輔助類 ?
? ? /// </summary> ?
? ? public class HttpWebResponseUtility ?
? ? { ?
? ? ? ? private static readonly string DefaultUserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"; ?
? ? ? ? /// <summary> ?
? ? ? ? /// 創(chuàng)建GET方式的HTTP請(qǐng)求 ?
? ? ? ? /// </summary> ?
? ? ? ? /// <param name="url">請(qǐng)求的URL</param> ?
? ? ? ? /// <param name="timeout">請(qǐng)求的超時(shí)時(shí)間</param> ?
? ? ? ? /// <param name="userAgent">請(qǐng)求的客戶端瀏覽器信息,可以為空</param> ?
? ? ? ? /// <param name="cookies">隨同HTTP請(qǐng)求發(fā)送的Cookie信息,如果不需要身份驗(yàn)證可以為空</param> ?
? ? ? ? /// <returns></returns> ?
? ? ? ? public static HttpWebResponse CreateGetHttpResponse(string url,int? timeout, string userAgent,CookieCollection cookies) ?
? ? ? ? { ?
? ? ? ? ? ? if (string.IsNullOrEmpty(url)) ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? throw new ArgumentNullException("url"); ?
? ? ? ? ? ? } ?
? ? ? ? ? ? HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; ?
? ? ? ? ? ? request.Method = "GET"; ?
? ? ? ? ? ? request.UserAgent = DefaultUserAgent; ?
? ? ? ? ? ? if (!string.IsNullOrEmpty(userAgent)) ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? request.UserAgent = userAgent; ?
? ? ? ? ? ? } ?
? ? ? ? ? ? if (timeout.HasValue) ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? request.Timeout = timeout.Value; ?
? ? ? ? ? ? } ?
? ? ? ? ? ? if (cookies != null) ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? request.CookieContainer = new CookieContainer(); ?
? ? ? ? ? ? ? ? request.CookieContainer.Add(cookies); ?
? ? ? ? ? ? } ?
? ? ? ? ? ? return request.GetResponse() as HttpWebResponse; ?
? ? ? ? } ?
? ? ? ? /// <summary> ?
? ? ? ? /// 創(chuàng)建POST方式的HTTP請(qǐng)求 ?
? ? ? ? /// </summary> ?
? ? ? ? /// <param name="url">請(qǐng)求的URL</param> ?
? ? ? ? /// <param name="parameters">隨同請(qǐng)求POST的參數(shù)名稱及參數(shù)值字典</param> ?
? ? ? ? /// <param name="timeout">請(qǐng)求的超時(shí)時(shí)間</param> ?
? ? ? ? /// <param name="userAgent">請(qǐng)求的客戶端瀏覽器信息,可以為空</param> ?
? ? ? ? /// <param name="requestEncoding">發(fā)送HTTP請(qǐng)求時(shí)所用的編碼</param> ?
? ? ? ? /// <param name="cookies">隨同HTTP請(qǐng)求發(fā)送的Cookie信息,如果不需要身份驗(yàn)證可以為空</param> ?
? ? ? ? /// <returns></returns> ?
? ? ? ? public static HttpWebResponse CreatePostHttpResponse(string url,IDictionary<string,string> parameters,int? timeout, string userAgent,Encoding requestEncoding,CookieCollection cookies) ?
? ? ? ? { ?
? ? ? ? ? ? if (string.IsNullOrEmpty(url)) ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? throw new ArgumentNullException("url"); ?
? ? ? ? ? ? } ?
? ? ? ? ? ? if(requestEncoding==null) ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? throw new ArgumentNullException("requestEncoding"); ?
? ? ? ? ? ? } ?
? ? ? ? ? ? HttpWebRequest request=null; ?
? ? ? ? ? ? //如果是發(fā)送HTTPS請(qǐng)求 ?
? ? ? ? ? ? if(url.StartsWith("https",StringComparison.OrdinalIgnoreCase)) ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); ?
? ? ? ? ? ? ? ? request = WebRequest.Create(url) as HttpWebRequest; ?
? ? ? ? ? ? ? ? request.ProtocolVersion=HttpVersion.Version10; ?
? ? ? ? ? ? } ?
? ? ? ? ? ? else?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? request = WebRequest.Create(url) as HttpWebRequest; ?
? ? ? ? ? ? } ?
? ? ? ? ? ? request.Method = "POST"; ?
? ? ? ? ? ? request.ContentType = "application/x-www-form-urlencoded"; ?
? ? ? ? ? ? ??
? ? ? ? ? ? if (!string.IsNullOrEmpty(userAgent)) ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? request.UserAgent = userAgent; ?
? ? ? ? ? ? } ?
? ? ? ? ? ? else?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? request.UserAgent = DefaultUserAgent; ?
? ? ? ? ? ? } ?
?
? ? ? ? ? ? if (timeout.HasValue) ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? request.Timeout = timeout.Value; ?
? ? ? ? ? ? } ?
? ? ? ? ? ? if (cookies != null) ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? request.CookieContainer = new CookieContainer(); ?
? ? ? ? ? ? ? ? request.CookieContainer.Add(cookies); ?
? ? ? ? ? ? } ?
? ? ? ? ? ? //如果需要POST數(shù)據(jù) ?
? ? ? ? ? ? if(!(parameters==null||parameters.Count==0)) ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? StringBuilder buffer = new StringBuilder(); ?
? ? ? ? ? ? ? ? int i = 0; ?
? ? ? ? ? ? ? ? foreach (string key in parameters.Keys) ?
? ? ? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? ? ? if (i > 0) ?
? ? ? ? ? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? ? ? ? ? buffer.AppendFormat("&{0}={1}", key, parameters[key]); ?
? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? ? ? else?
? ? ? ? ? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? ? ? ? ? buffer.AppendFormat("{0}={1}", key, parameters[key]); ?
? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? ? ? i++; ?
? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? byte[] data = requestEncoding.GetBytes(buffer.ToString()); ?
? ? ? ? ? ? ? ? using (Stream stream = request.GetRequestStream()) ?
? ? ? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? ? ? stream.Write(data, 0, data.Length); ?
? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? } ?
? ? ? ? ? ? return request.GetResponse() as HttpWebResponse; ?
? ? ? ? } ?
?
? ? ? ? private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) ?
? ? ? ? { ?
? ? ? ? ? ? return true; //總是接受 ?
? ? ? ? } ?
? ? } ?
}?
?從上面的代碼中可以看出POST數(shù)據(jù)到HTTP和HTTPS站點(diǎn)不同,POST數(shù)據(jù)到HTTPS站點(diǎn)的時(shí)候需要設(shè)置ServicePointManager類的ServerCertificateValidationCallback屬性,并且在POST到https://passport.baidu.com/?login時(shí)還需要將HttpWebResquest實(shí)例的ProtocolVersion屬性設(shè)置為HttpVersion.Version10(這個(gè)未驗(yàn)證是否所有的HTTPS站點(diǎn)都需要設(shè)置),否則在調(diào)用GetResponse()方法時(shí)會(huì)拋出“基礎(chǔ)連接已經(jīng)關(guān)閉: 連接被意外關(guān)閉。”的異常。
?
?用法舉例
?這個(gè)類用起來也很簡單:
?(1)POST數(shù)據(jù)到HTTPS站點(diǎn),用它來登錄百度:
?
string loginUrl = "https://passport.baidu.com/?login"; ?
string userName = "userName"; ?
string password = "password"; ?
string tagUrl = "http://cang.baidu.com/"+userName+"/tags"; ?
Encoding encoding = Encoding.GetEncoding("gb2312"); ?
?
IDictionary<string, string> parameters = new Dictionary<string, string>(); ?
parameters.Add("tpl", "fa"); ?
parameters.Add("tpl_reg", "fa"); ?
parameters.Add("u", tagUrl); ?
parameters.Add("psp_tt", "0"); ?
parameters.Add("username", userName); ?
parameters.Add("password", password); ?
parameters.Add("mem_pass", "1"); ?
HttpWebResponse response = HttpWebResponseUtility.CreatePostHttpResponse(loginUrl, parameters, null, null, encoding, null); ?
string cookieString = response.Headers["Set-Cookie"];?
?(2)發(fā)送GET請(qǐng)求到HTTP站點(diǎn)
?在cookieString中包含了服務(wù)器端返回的會(huì)話信息數(shù)據(jù),從中提取了之后可以設(shè)置Cookie下次登錄時(shí)帶上這個(gè)Cookie就可以以認(rèn)證用戶的信息,假設(shè)我們已經(jīng)登錄成功并且獲取了Cookie,那么發(fā)送GET請(qǐng)求的代碼如下:
?
string userName = "userName"; ?
string tagUrl = "http://cang.baidu.com/"+userName+"/tags"; ?
CookieCollection cookies = new CookieCollection();//如何從response.Headers["Set-Cookie"];中獲取并設(shè)置CookieCollection的代碼略 ?
response = HttpWebResponseUtility.CreateGetHttpResponse(tagUrl, null, null, cookies); ?
?(3)發(fā)送POST請(qǐng)求到HTTP站點(diǎn)
?以登錄51CTO為例:
?
string loginUrl = "http://home.51cto.com/index.php?s=/Index/doLogin"; ?
string userName = "userName"; ?
string password = "password"; ?
?
IDictionary<string, string> parameters = new Dictionary<string, string>(); ?
parameters.Add("email", userName); ?
parameters.Add("passwd", password); ?
?
HttpWebResponse response = HttpWebResponseUtility.CreatePostHttpResponse(loginUrl, parameters, null, null, Encoding.UTF8, null); ?
?在這里說句題外話,CSDN的登錄處理是由http://passport.csdn.net/ajax/accounthandler.ashx這個(gè)Handler來處理的。
?
?總結(jié)
在本文只是講解了在C#中發(fā)送請(qǐng)求到HTTP和HTTPS的用法,分GET/POST兩種方式,為減少一些繁瑣和機(jī)械的編碼,周公將其封裝為一個(gè)類,發(fā)送數(shù)據(jù)之后返回HttpWebResponse對(duì)象實(shí)例,利用這個(gè)實(shí)例我們可以獲取服務(wù)器端返回的Cookie以便用認(rèn)證用戶的身份繼續(xù)發(fā)送請(qǐng)求,或者讀取服務(wù)器端響應(yīng)的內(nèi)容,不過在讀取響應(yīng)內(nèi)容時(shí)要注意響應(yīng)格式和編碼,本來在這個(gè)類中還有讀取HTML和WML內(nèi)容的方法(包括服務(wù)器使用壓縮方式傳輸?shù)臄?shù)據(jù)),但限于篇幅和其它方面的原因,此處省略掉了。如有機(jī)會(huì),在以后的文章中會(huì)繼續(xù)講述這方面的內(nèi)容。
========
http協(xié)議post數(shù)據(jù)標(biāo)準(zhǔn)格式 ?
http://blog.163.com/wu_ernan/blog/static/2102880202014226102528240/在C#中有HttpWebRequest類,可以很方便用來獲取http請(qǐng)求,但是這個(gè)類對(duì)Post方式?jīng)]有提供一個(gè)很方便的方法來獲取數(shù)據(jù)。網(wǎng)上有很多人提供了解決方法,但都參差不齊,這里我把我使用的方法總結(jié)出來,與大家分享。
?
本文精華:實(shí)現(xiàn)了post的時(shí)候即可以有字符串的key-value,還可以帶文件。
?
Post數(shù)據(jù)格式
?
Post提交數(shù)據(jù)的時(shí)候最重要就是把Key-Value的數(shù)據(jù)放到http請(qǐng)求流中,而HttpWebRequest沒有提供一個(gè)屬性之類的東西可以讓我們自由添加Key-Value,因此就必須手工構(gòu)造這個(gè)數(shù)據(jù)。
根據(jù)RFC 2045協(xié)議,一個(gè)Http Post的數(shù)據(jù)格式如下:
Content-Type: multipart/form-data; boundary=AaB03x
?
?--AaB03x
?Content-Disposition: form-data; name="submit-name"
?
?Larry
?--AaB03x
?Content-Disposition: form-data; name="file"; filename="file1.dat"
?Content-Type: application/octet-stream
?
?... contents of file1.dat ...
?--AaB03x--
詳細(xì)解釋如下:
Content-Type: multipart/form-data; boundary=AaB03x
?
如上面所示,首先聲明數(shù)據(jù)類型為multipart/form-data, 然后定義邊界字符串AaB03x,這個(gè)邊界字符串就是用來在下面來區(qū)分各個(gè)數(shù)據(jù)的,可以隨便定義,但是最好是用破折號(hào)等數(shù)據(jù)中一般不會(huì)出現(xiàn)的字符。然后是換行符。
注意:Post中定義的換行符是\r\n
--AaB03x
?
這個(gè)是邊界字符串,注意每一個(gè)邊界符前面都需要加2個(gè)連字符“--”,然后跟上換行符。
Content-Disposition: form-data; name="submit-name"
?
這里是Key-Value數(shù)據(jù)中字符串類型的數(shù)據(jù)。submit-name 是這個(gè)Key-Value數(shù)據(jù)中的Key。當(dāng)然也需要換行符。
Larry
?
這個(gè)就是剛才Key-Value數(shù)據(jù)中的value。
--AaB03x
?
邊界符,表示數(shù)據(jù)結(jié)束。
Content-Disposition: form-data; name="file"; filename="file1.dat"
?
這個(gè)代表另外一個(gè)數(shù)據(jù),它的key是file,文件名是file1.dat。 注意:最后面沒有分號(hào)了。
Content-Type: application/octet-stream
?
這個(gè)標(biāo)識(shí)文件類型。application/octet-stream表示二進(jìn)制數(shù)據(jù)。
... contents of file1.dat ...
?
這個(gè)是文件內(nèi)容??梢允苟M(jìn)制的數(shù)據(jù)。
--AaB03x--
?
數(shù)據(jù)結(jié)束后的分界符,注意因?yàn)檫@個(gè)后面沒有數(shù)據(jù)了所以需要在后面追加一個(gè)“--”表示結(jié)束。
C#下Post數(shù)據(jù)的函數(shù)
?
搞明白格式后,我們就很容易寫出C#的代碼了。如下所示:
private static string HttpPostData(string url, int timeOut, string fileKeyName,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? string filePath, NameValueCollection stringDict)
{
? ? string responseContent;
? ? var memStream = new MemoryStream();
? ? var webRequest = (HttpWebRequest)WebRequest.Create(url);
? ? // 邊界符
? ? var boundary = "---------------" + DateTime.Now.Ticks.ToString("x");
? ? // 邊界符
? ? var beginBoundary = Encoding.ASCII.GetBytes("--" + boundary + "\r\n");
? ? var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
? ? // 最后的結(jié)束符
? ? var endBoundary = Encoding.ASCII.GetBytes("--" + boundary + "--\r\n");
?
? ? // 設(shè)置屬性
? ? webRequest.Method = "POST";
? ? webRequest.Timeout = timeOut;
? ? webRequest.ContentType = "multipart/form-data; boundary=" + boundary;
?
? ? // 寫入文件
? ? const string filePartHeader =
? ? ? ? "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n"+
? ? ? ? ?"Content-Type: application/octet-stream\r\n\r\n";
? ? var header = string.Format(filePartHeader, fileKeyName, filePath);
? ? var headerbytes = Encoding.UTF8.GetBytes(header);
?
? ? memStream.Write(beginBoundary, 0, beginBoundary.Length);
? ? memStream.Write(headerbytes, 0, headerbytes.Length);
?
? ? var buffer = new byte[1024];
? ? int bytesRead; // =0
?
? ? while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
? ? {
? ? ? ? memStream.Write(buffer, 0, bytesRead);
? ? }
?
? ? // 寫入字符串的Key
? ? var stringKeyHeader = "\r\n--" + boundary +
? ? ? ? ? ? ? ? ? ? ? ? ? ?"\r\nContent-Disposition: form-data; name=\"{0}\""+
? ? ? ? ? ? ? ? ? ? ? ? ? ?"\r\n\r\n{1}\r\n";
?
? ? foreach (byte[] formitembytes in from string key in stringDict.Keys
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?select string.Format(stringKeyHeader, key, stringDict[key])
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?into formitem
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?select Encoding.UTF8.GetBytes(formitem))
? ? {
? ? ? ? memStream.Write(formitembytes, 0, formitembytes.Length);
? ? }
?
? ? // 寫入最后的結(jié)束邊界符
? ? memStream.Write(endBoundary, 0, endBoundary.Length);
?
? ? webRequest.ContentLength = memStream.Length;
?
? ? var requestStream = webRequest.GetRequestStream();
?
? ? memStream.Position = 0;
? ? var tempBuffer = new byte[memStream.Length];
? ? memStream.Read(tempBuffer, 0, tempBuffer.Length);
? ? memStream.Close();
?
? ? requestStream.Write(tempBuffer, 0, tempBuffer.Length);
? ? requestStream.Close();
?
? ? var httpWebResponse = (HttpWebResponse)webRequest.GetResponse();
?
? ? using (var httpStreamReader = new StreamReader(httpWebResponse.GetResponseStream(),
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Encoding.GetEncoding("utf-8")))
? ? {
? ? ? ? responseContent = httpStreamReader.ReadToEnd();
? ? }
?
? ? fileStream.Close();
? ? httpWebResponse.Close();
? ? webRequest.Abort();
?
? ? return responseContent;
}
參考資料
Rfc2045:http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.
http://stackoverflow.com/questions/566462/upload-files-with-httpwebrequest-multipart-form-data
========
總結(jié)
以上是生活随笔為你收集整理的C# 操作http协议学习总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ASPNet_Compiler学习总结
- 下一篇: C#内存映射文件学习总结