C#实现http协议支持上传下载文件的GET、POST请求

C#实现http协议支持上传下载文件的GET、POST请求
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.loopc.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就带上Cookie

if (cookie != "") { headers += "Cookie:" + cookie + "/r/n"; }

//空行,请求头结束

headers += "/r/n";

strRequestHeaders = headers;

requestHeaders.Clear();

return encoding.GetBytes(headers);

}

///<summary>

///获取服务器响应文本

///</summary>

///<returns>服务器响应文本</returns>

private string GetHtml()

{

MemoryStream ms = new MemoryStream();

SaveNetworkStream(ms);//将网络流保存到内存流

StreamReader sr = new StreamReader(ms, encoding);

respHtml = sr.ReadToEnd();

sr.Close(); ms.Close();

return respHtml;

}

///<summary>

///将网络流保存到指定流

///</summary>

///<param name="toStream">保存位置</param>

///<param name="needProgress">是否显示进度</param>

private void SaveNetworkStream(Stream toStream, bool showProgress)

{

//获取要保存的网络流

NetworkStream NetStream = clientSocket.GetStream();

byte[] buffer = new byte[RECEIVE_BUFFER_SIZE];

int count = 0, startIndex = 0;

MemoryStream ms = new MemoryStream();

for (int i = 0; i < 3; i++)

{

count = NetStream.Read(buffer, 0, 500);

ms.Write(buffer, 0, count);

}

if (ms.Length == 0) { NetStream.Close(); throw new Exception("远程服务器没有响应"); }

buffer = ms.GetBuffer();

count = (int)ms.Length;

GetResponseHeader(buffer, out startIndex);//分析响应,获取响应头和响应实体

count -= startIndex;

toStream.Write(buffer, startIndex, count);

DownloadEventArgs e = new DownloadEventArgs();

if (responseHeaders["Content-Length"] != null)

{ e.totalBytes = long.Parse(responseHeaders["Content-Length"]); }

else

{ e.totalBytes = -1; }

//启动计时器

System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();

timer.Start();

do

{

//如果取消就推出

if (isCanceled) { break; }

//显示下载进度

if (showProgress)

{

e.bytesReceived += count;

e.ReceiveProgress = (double)e.bytesReceived / (double)e.totalBytes;

byte[] tempBuffer = new byte[count];

Array.Copy(buffer, startIndex, tempBuffer, 0, count);

e.receivedBuffer = tempBuffer;

double t = (timer.ElapsedMilliseconds + 0.1)/1000;

e.receiveSpeed = (double)e.bytesReceived / t;

startIndex = 0;

if (DownloadProgressChanged != null) { DownloadProgressChanged(this, e); }

}

//读取网路数据到缓冲区

count = NetStream.Read(buffer, 0, buffer.Length);

//将缓存区数据保存到指定流

toStream.Write(buffer, 0, count);

} while (count > 0);

timer.Stop();//关闭计时器

if (responseHeaders["Content-Length"] != null)

{

toStream.SetLength(long.Parse(responseHeaders["Content-Length"]));

}

//else

//{

//    toStream.SetLength(toStream.Length);

//    responseHeaders.Add("Content-Length", toStream.Length.ToString());//添加响应标头

//}

toStream.Position = 0;

//关闭网络流和网络连接

NetStream.Close();

clientSocket.Close();

}

///<summary>

///将网络流保存到指定流

///</summary>

///<param name="toStream">保存位置</param>

private void SaveNetworkStream(Stream toStream)

{

SaveNetworkStream(toStream, false);

}

///<summary>

///分析响应流,去掉响应头

///</summary>

///<param name="buffer"></param>

private void GetResponseHeader(byte[] buffer, out int startIndex)

{

responseHeaders.Clear();

string html = encoding.GetString(buffer);

StringReader sr = new StringReader(html);

int start = html.IndexOf("/r/n/r/n") + 4;//找到空行位置

strResponseHeaders = html.Substring(0, start);//获取响应头文本

//获取响应状态码

//

if (sr.Peek() > -1)

{

//读第一行字符串

string line = sr.ReadLine();

//分析此行字符串,获取服务器响应状态码

Match M = RE.Match(line, @"/d/d/d");

if (M.Success)

{

statusCode = int.Parse(M.Value);

}

}

//获取响应头

//

while (sr.Peek() > -1)

{

//读一行字符串

string line = sr.ReadLine();

//若非空行

if (line != "")

{

//分析此行字符串,获取响应标头

Match M = RE.Match(line, "([^:]+):(.+)");

if (M.Success)

{

try

{        //添加响应标头到集合

responseHeaders.Add(M.Groups[1].Value.Trim(), M.Groups[2].Value.Trim());

}

catch

{ }

//获取Cookie

if (M.Groups[1].Value == "Set-Cookie")

{

M = RE.Match(M.Groups[2].Value, "[^=]+=[^;]+");

cookie += M.Value.Trim() + ";";

}

}

}

//若是空行,代表响应头结束响应实体开始。(响应头和响应实体间用一空行隔开)

else

{

//如果响应头中没有实体大小标头,尝试读响应实体第一行获取实体大小

if (responseHeaders["Content-Length"] == null && sr.Peek() > -1)

{

//读响应实体第一行

line = sr.ReadLine();

//分析此行看是否包含实体大小

Match M = RE.Match(line, "~[0-9a-fA-F]{1,15}");

if (M.Success)

{

//将16进制的实体大小字符串转换为10进制

int length = int.Parse(M.Value, System.Globalization.NumberStyles.AllowHexSpecifier);

responseHeaders.Add("Content-Length", length.ToString());//添加响应标头

strResponseHeaders += M.Value + "/r/n";

}

}

break;//跳出循环

}//End If

}//End While

sr.Close();

//实体开始索引

startIndex = encoding.GetBytes(strResponseHeaders).Length;

}

///<summary>

///取消上传或下载,要继续开始请调用Start方法

///</summary>

public void Cancel()

{

isCanceled = true;

}

///<summary>

///启动上传或下载,要取消请调用Cancel方法

///</summary>

public void Start()

{

isCanceled = false;

}

//*************************************************************

//以下为属性

//*************************************************************

///<summary>

///获取或设置请求头

///</summary>

public WebHeaderCollection RequestHeaders

{

set { requestHeaders = value; }

get { return requestHeaders; }

}

///<summary>

///获取响应头集合

///</summary>

public WebHeaderCollection ResponseHeaders

{

get { return responseHeaders; }

}

///<summary>

///获取请求头文本

///</summary>

public string StrRequestHeaders

{

get { return strRequestHeaders; }

}

///<summary>

///获取响应头文本

///</summary>

public string StrResponseHeaders

{

get { return strResponseHeaders; }

}

///<summary>

///获取或设置Cookie

///</summary>

public string Cookie

{

set { cookie = value; }

get { return cookie; }

}

///<summary>

///获取或设置编码方式(默认为系统默认编码方式)

///</summary>

public Encoding Encoding

{

set { encoding = value; }

get { return encoding; }

}

///<summary>

///获取服务器响应文本

///</summary>

public string RespHtml

{

get { return respHtml; }

}

///<summary>

///获取服务器响应状态码

///</summary>

public int StatusCode

{

get { return statusCode; }

}

}

}

时间: 2024-08-04 23:24:53

C#实现http协议支持上传下载文件的GET、POST请求的相关文章

winform通过FTP协议上传下载文件

上传文件:窗体代码 一次上传多个文件(grdAffixFilesList中需要上传的) private Boolean UploadFile() { string filename; int upCount=0; for (int i = 0; i < this.grdAffixFilesList.Rows.Count; i++) { filename = this.grdAffixFilesList.Rows[i].Cells["FILEPATH"].Text.ToString

向云服务器上传下载文件方法汇总(转)

转载于:https://yq.aliyun.com/articles/64700 摘要: 一.向Windows服务器上传下载文件方式 方法有很多种,此处介绍远程桌面的本地资源共享方法. 1.运行mstsc,连接远程桌面的时候,点"选项>>" 2."本地资源"-->详细信息. 3."磁盘驱动器"前面打钩. 一.向Windows服务器上传下载文件方式 方法有很多种,此处介绍远程桌面的本地资源共享方法. 1.运行mstsc,连接远程桌

向linux服务器上传下载文件方式收集

向linux服务器上传下载文件方式收集 1. scp [优点]简单方便,安全可靠:支持限速参数[缺点]不支持排除目录[用法] scp就是secure copy,是用来进行远程文件拷贝的.数据传输使用 ssh,并且和ssh 使用相同的认证方式,提供相同的安全保证 . 命令格式: scp [参数] <源地址(用户名@IP地址或主机名)>:<文件路径> <目的地址(用户名 @IP 地址或主机名)>:<文件路径> 举例: scp /home/work/source.

经验分享] 向云服务器上传下载文件方法汇总

一.向Windows服务器上传下载文件方式 方法有很多种,此处介绍远程桌面的本地资源共享方法. 1.运行mstsc,连接远程桌面的时候,点"选项>>" <ignore_js_op> 2."本地资源"-->详细信息. <ignore_js_op> 3."磁盘驱动器"前面打钩. <ignore_js_op> 4.连接远程电脑后,打开"我的电脑",就能看到刚刚共享的硬盘驱动器.把

利用 secureCRT 直接上传下载文件 (sz,rz)

在window下向linux传送文件的方法. 首先在window中安装SecureCRT,然后在快速连接中建立一个到linux的连接,当然,你要先知道你的系统的ip,在终端中键入ifconfig可以查看到. 然后连接即可登陆到linux的终端下 要从linux传文件到window的话,这需要cd到你要传的文件的目录,然后用命令:sz 文件名即可上传.文件放在securesrt/download下面 要从window传送文件到linux,则在终端中输入rz,然后会出来一个对话框让你选择文件传送的.

SecureCRT上传下载文件教程(Zmodem使用教程)

SecureCRT是一个仿真终端连接工具.它可以方便的连接SSH服务器,远程管理Linux.同时,它还能使用多种协议方便的上传下载文件.其中Zmodem是SecureCRT支持比较好的一种古老的上传下载协议. 要使用Zmodem上传下载,必须要在Linux中安装相应的软件.否则SecureCRT无法正常上传或下载.在CentOS与Debian中,这个软件的名字叫“lrzsz”.下面将介绍其安装与使用方法. 安装lrzsz(zmodem) 1 [[email protected] ~]#apt-g

Linux上传下载文件

2种方式:xftp(工具).lrzsz xftp:协议--SFTP.端口号--22 lrzsz: rz,sz是Linux/Unix同Windows进行ZModem文件传输的命令行工具. 优点就是不用再开一个sftp工具登录上去上传下载文件. sz(下载):将选定的文件发送(send)到本地机器 rz(上传):运行该命令会弹出一个文件选择窗口,从本地选择文件上传到Linux服务器 安装命令:yum install lrzsz 从服务端发送文件到客户端:sz filename 从客户端上传文件到服务

SFTP上传下载文件

secureCRT SFTP上传/下载文件 远程登陆IP secureCRT会话中点击SFTP 3.cd  /home/dowload       linux平台切换到/home/dowload目录 4.cd d:\   windows平台切换到d盘 5.put 文件名           上传 /home/dowload目录下 6.get 文件名   下载文件到windows平台 d盘

rz和sz上传下载文件工具lrzsz

######################### rz和sz上传下载文件工具lrzsz ############################################################ 1 rpm -qa |grep lrzsz 如果没有用RPM安装即可: 2 rpm -ivh lrzsz-0.12.20-27.1.el6.x86_64.rpm (去光盘里找) 或者 yum install -y lrzsz 即可. ###########################