using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Collections;
using System.IO;
using System.Text.RegularExpressions;
using RE = System.Text.RegularExpressions.Regex ;
using System.Security.Cryptography.X509Certificates;
/***************************************************************************************************************************************************
* * 文件名:HttpProc.cs
* * 创建人:HeDaode
* * 日 期:2007.09.01
* * 描 述:实现HTTP协议中的GET、POST请求
* * 使 用:HttpProc.WebClient client = new HttpProc.WebClient();
client.Encoding = System.Text.Encoding.Default;// 默认编码方式,根据需要设置其他类型
client.OpenRead("http://www.baidu.com");// 普通get请求
MessageBox.Show(client.RespHtml);// 获取返回的网页源代码
client.DownloadFile("http://www.codepub.com/upload/163album.rar",@"C:\163album.rar");// 下载文件
client.OpenRead("http://passport.baidu.com/?login","username=zhangsan&password=123456");// 提交表单,此处是登录百度的示例
client.UploadFile("http://hiup.baidu.com/zhangsan/upload", @"file1=D:\1.mp3");// 上传文件
client.UploadFile("http://hiup.baidu.com/zhangsan/upload", "folder=myfolder&size=4003550",@"file1=D:\1.mp3");// 提交含文本域和文件域的表单
*****************************************************************************************************************************************************/
namespace HttpProc
{
/// <summary>
/// 上传事件委托
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public delegate void WebClientUploadEvent (object sender, HttpProc.UploadEventArgs e);
/// <summary>
/// 下载事件委托
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public delegate void WebClientDownloadEvent (object sender, HttpProc.DownloadEventArgs e);
/// <summary>
/// 上传事件参数
/// </summary>
public struct UploadEventArgs
{
/// <summary>
/// 上传数据总大小
/// </summary>
public long totalBytes;
/// <summary>
/// 已发数据大小
/// </summary>
public long bytesSent;
/// <summary>
/// 发送进度(0-1)
/// </summary>
public double sendProgress;
/// <summary>
/// 发送速度Bytes/s
/// </summary>
public double sendSpeed;
}
/// <summary>
/// 下载事件参数
/// </summary>
public struct DownloadEventArgs
{
/// <summary>
/// 下载数据总大小
/// </summary>
public long totalBytes;
/// <summary>
/// 已接收数据大小
/// </summary>
public long bytesReceived;
/// <summary>
/// 接收数据进度(0-1)
/// </summary>
public double ReceiveProgress;
/// <summary>
/// 当前缓冲区数据
/// </summary>
public byte [] receivedBuffer;
/// <summary>
/// 接收速度Bytes/s
/// </summary>
public double receiveSpeed;
}
/// <summary>
/// 实现向WEB服务器发送和接收数据
/// </summary>
public class WebClient
{
private WebHeaderCollection requestHeaders, responseHeaders;
private TcpClient clientSocket;
private MemoryStream postStream;
private Encoding encoding = Encoding .Default;
private const string BOUNDARY = "--HEDAODE--" ;
private const int SEND_BUFFER_SIZE = 10245;
private const int RECEIVE_BUFFER_SIZE = 10245;
private string cookie = "" ;
private string respHtml = "" ;
private string strRequestHeaders = "" ;
private string strResponseHeaders = "" ;
private int statusCode = 0;
private bool isCanceled = false ;
public event WebClientUploadEvent UploadProgressChanged;
public event WebClientDownloadEvent DownloadProgressChanged;
/// <summary>
/// 初始化WebClient类
/// </summary>
public WebClient()
{
responseHeaders = new WebHeaderCollection ();
requestHeaders = new WebHeaderCollection ();
}
/// <summary>
/// 读取指定URL的文本
/// </summary>
/// <param name="URL"> 请求的地址 </param>
/// <returns> 服务器响应文本 </returns>
public string OpenRead(string URL)
{
requestHeaders.Add("Connection" , "close" );
SendRequestData(URL, "GET" );
return GetHtml();
}
// 解决证书过期无法访问的问题
class CertPolicy : ICertificatePolicy
{
public bool CheckValidationResult(ServicePoint srvpt, X509Certificate cert, WebRequest req, int certprb)
{ return true ; }
}
/// <summary>
/// 采用https协议访问网络
/// </summary>
/// <param name="URL"> url 地址 </param>
/// <param name="strPostdata"> 发送的数据 </param>
/// <returns></returns>
public string OpenReadWithHttps(string URL,string strPostdata)
{
ServicePointManager .CertificatePolicy = new CertPolicy ();
HttpWebRequest request = (HttpWebRequest )WebRequest .Create(URL);
request.CookieContainer = new CookieContainer ();
request.Method = "POST" ;
request.Accept = "*/*" ;
request.ContentType="application/x-www-form-urlencoded" ;
byte [] buffer = this .encoding.GetBytes(strPostdata);
request.ContentLength = buffer.Length;
request.GetRequestStream().Write(buffer, 0, buffer.Length);
HttpWebResponse response = (HttpWebResponse )request.GetResponse();
StreamReader reader = new StreamReader (response.GetResponseStream(), encoding);
this .respHtml = reader.ReadToEnd();
foreach (System.Net.Cookie ck in response.Cookies)
{
this .cookie += ck.Name + "=" + ck.Value + ";" ;
}
reader.Close();
return respHtml;
}
/// <summary>
/// 读取指定URL的文本
/// </summary>
/// <param name="URL"> 请求的地址 </param>
/// <param name="postData"> 向服务器发送的文本数据 </param>
/// <returns> 服务器响应文本 </returns>
public string OpenRead(string URL, string postData)
{
byte [] sendBytes = encoding.GetBytes(postData);
postStream = new MemoryStream ();
postStream.Write(sendBytes, 0, sendBytes.Length);
requestHeaders.Add("Content-Length" , postStream.Length.ToString());
requestHeaders.Add("Content-Type" , "application/x-www-form-urlencoded" );
requestHeaders.Add("Connection" , "close" );
SendRequestData(URL, "POST" );
return GetHtml();
}
/// <summary>
/// 读取指定URL的流
/// </summary>
/// <param name="URL"> 请求的地址 </param>
/// <param name="postData"> 向服务器发送的数据 </param>
/// <returns> 服务器响应流 </returns>
public Stream GetStream(string URL, string postData)
{
byte [] sendBytes = encoding.GetBytes(postData);
postStream = new MemoryStream ();
postStream.Write(sendBytes, 0, sendBytes.Length);
requestHeaders.Add("Content-Length" , postStream.Length.ToString());
requestHeaders.Add("Content-Type" , "application/x-www-form-urlencoded" );
requestHeaders.Add("Connection" , "close" );
SendRequestData(URL, "POST" );
MemoryStream ms = new MemoryStream ();
SaveNetworkStream(ms);
return ms;
}
/// <summary>
/// 上传文件到服务器
/// </summary>
/// <param name="URL"> 请求的地址 </param>
/// <param name="fileField"> 文件域(格式如:file1=C:\test.mp3&file2=C:\test.jpg) </param>
/// <returns> 服务器响应文本 </returns>
public string UploadFile(string URL, string fileField)
{
return UploadFile(URL, "" , fileField);
}
/// <summary>
/// 上传文件和数据到服务器
/// </summary>
/// <param name="URL"> 请求地址 </param>
/// <param name="textField"> 文本域(格式为:name1=value1&name2=value2) </param>
/// <param name="fileField"> 文件域(格式如:file1=C:\test.mp3&file2=C:\test.jpg) </param>
/// <returns> 服务器响应文本 </returns>
public string UploadFile(string URL, string textField, string fileField)
{
postStream = new MemoryStream ();
if (textField != "" && fileField != "" )
{
WriteTextField(textField);
WriteFileField(fileField);
}
else if (fileField != "" )
{
WriteFileField(fileField);
}
else if (textField != "" )
{
WriteTextField(textField);
}
else
throw new Exception (" 文本域和文件域不能同时为空。" );
// 写入结束标记
byte [] buffer = encoding.GetBytes("--" + BOUNDARY + "--\r\n" );
postStream.Write(buffer, 0, buffer.Length);
// 添加请求标头
requestHeaders.Add("Content-Length" , postStream.Length.ToString());
requestHeaders.Add("Content-Type" , "multipart/form-data; boundary=" + BOUNDARY);
requestHeaders.Add("Connection" , "Keep-Alive" );
// 发送请求数据
SendRequestData(URL, "POST" , true );
// 返回响应文本
return GetHtml();
}
/// <summary>
/// 分析文本域,添加到请求流
/// </summary>
/// <param name="textField"> 文本域 </param>
private void WriteTextField(string textField)
{
string [] strArr = RE .Split(textField, "&" );
textField = "" ;
foreach (string var in strArr)
{
Match M = RE .Match(var, "([^=]+)=(.+)" );
textField += "--" + BOUNDARY + "\r\n" ;
textField += "Content-Disposition: form-data; name=\"" + M.Groups[1].Value + "\"\r\n\r\n" + M.Groups[2].Value + "\r\n" ;
}
byte [] buffer = encoding.GetBytes(textField);
postStream.Write(buffer, 0, buffer.Length);
}
/// <summary>
/// 分析文件域,添加到请求流
/// </summary>
/// <param name="fileField"> 文件域 </param>
private void WriteFileField(string fileField)
{
string filePath = "" ;
int count = 0;
string [] strArr = RE .Split(fileField, "&" );
foreach (string var in strArr)
, {
Match M = RE .Match(var, "([^=]+)=(.+)" );
filePath = M.Groups[2].Value;
fileField = "--" + BOUNDARY + "\r\n" ;
fileField += "Content-Disposition: form-data; name=\"" + M.Groups[1].Value + "\"; filename=\"" + Path .GetFileName(filePath) + "\"\r\n" ;
fileField += "Content-Type: image/jpeg\r\n\r\n" ;
byte [] buffer = encoding.GetBytes(fileField);
postStream.Write(buffer, 0, buffer.Length);
// 添加文件数据
FileStream fs = new FileStream (filePath, FileMode .Open, FileAccess .Read);
buffer = new byte [50000];
do
{
count = fs.Read(buffer, 0, buffer.Length);
postStream.Write(buffer, 0, count);
} while (count > 0);
fs.Close();
fs.Dispose();
fs = null ;
buffer = encoding.GetBytes("\r\n" );
postStream.Write(buffer, 0, buffer.Length);
}
}
/// <summary>
/// 从指定URL下载数据流
/// </summary>
/// <param name="URL"> 请求地址 </param>
/// <returns> 数据流 </returns>
public Stream DownloadData(string URL)
{
requestHeaders.Add("Connection" , "close" );
SendRequestData(URL, "GET" );
MemoryStream ms = new MemoryStream ();
SaveNetworkStream(ms, true );
return ms;
}
/// <summary>
/// 从指定URL下载文件
/// </summary>
/// <param name="URL"> 文件URL地址 </param>
/// <param name="fileName"> 文件保存路径,含文件名(如:C:\test.jpg) </param>
public void DownloadFile(string URL, string fileName)
{
requestHeaders.Add("Connection" , "close" );
SendRequestData(URL, "GET" );
FileStream fs = new FileStream (fileName, FileMode .Create);
SaveNetworkStream(fs, true );
fs.Close();
fs = null ;
}
/// <summary>
/// 向服务器发送请求
/// </summary>
/// <param name="URL"> 请求地址 </param>
/// <param name="method"> POST 或GET </param>
/// <param name="showProgress"> 是否显示上传进度 </param>
private void SendRequestData(string URL, string method, bool showProgress)
{
clientSocket = new TcpClient ();
Uri URI = new Uri (URL);
clientSocket.Connect(URI.Host, URI.Port);
requestHeaders.Add("Host" , URI.Host);
byte [] request = GetRequestHeaders(method + " " + URI.PathAndQuery + " HTTP/1.1" );
clientSocket.Client.Send(request);
// 若有实体内容就发送它
if (postStream != null )
{
byte [] buffer = new byte [SEND_BUFFER_SIZE];
int count = 0;
Stream sm = clientSocket.GetStream();
postStream.Position = 0;
UploadEventArgs e = new UploadEventArgs ();
e.totalBytes = postStream.Length;
System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch ();// 计时器
timer.Start();
do
{
// 如果取消就推出
if (isCanceled) { break ; }
// 读取要发送的数据
count = postStream.Read(buffer, 0, buffer.Length);
// 发送到服务器
sm.Write(buffer, 0, count);
// 是否显示进度
if (showProgress)
{
// 触发事件
e.bytesSent += count;
e.sendProgress = (double )e.bytesSent / (double )e.totalBytes;
double t = timer.ElapsedMilliseconds / 1000;
t = t <= 0 ? 1 : t;
e.sendSpeed = (double )e.bytesSent / t;
if (UploadProgressChanged != null ) { UploadProgressChanged(this , e); }
}
} while (count > 0);
timer.Stop();
postStream.Close();
//postStream.Dispose();
postStream = null ;
}//end if
}
/// <summary>
/// 向服务器发送请求
/// </summary>
/// <param name="URL"> 请求URL地址 </param>
/// <param name="method"> POST 或GET </param>
private void SendRequestData(string URL, string method)
{
SendRequestData(URL, method, false );
}
/// <summary>
/// 获取请求头字节数组
/// </summary>
/// <param name="request"> POST 或GET请求 </param>
/// <returns> 请求头字节数组 </returns>
private byte [] GetRequestHeaders(string request)
{
requestHeaders.Add("Accept" , "*/*" );
requestHeaders.Add("Accept-Language" , "zh-cn" );
requestHeaders.Add("User-Agent" , "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)" );
string headers = request + "\r\n" ;
foreach (string key in requestHeaders)
{
headers += key + ":" + requestHeaders[key] + "\r\n" ;
}
// 有Cookie就带上Cooki
C#实现http协议GET、POST请求
最新推荐文章于 2024-05-18 16:36:40 发布