`

C#实现http协议GET、POST请求

    博客分类:
  • .NET
阅读更多

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请求封装类

    本文将详细讨论如何在C#中封装一个用于执行HTTP GET和POST请求的类,以及`HttpHelper.cs`文件中的关键实现。 首先,了解GET和POST的基本概念。GET请求通常用于获取资源,其参数通过URL查询字符串传递,且对数据量有...

    c# http协议,实现get或post发送请求 并返回内容

    本篇将详细介绍如何在C#中利用HTTP协议实现GET和POST请求,并获取返回的内容。 首先,让我们了解GET和POST的基本概念: 1. GET:GET请求是最常见的HTTP方法,用于从服务器获取资源。参数通常附加在URL后面,可见且...

    C#实现HTTP GET和POST 样例代码

    本文将深入探讨如何使用C#编程语言来实现HTTP GET和POST请求,以供学习者参考。 GET和POST是HTTP协议中最常见的两种请求方法。GET用于获取资源,而POST则常用于提交数据。 **HTTP GET方法** GET请求通常用于获取...

    C#的http发送post和get请求源码

    通过上述知识点,我们可以构建一个简单的C#应用程序,用于测试HTTP GET和POST请求。这个程序可能包含一个窗口,用户输入请求参数,点击按钮后,程序使用`HttpClient`发送请求,并将结果展示在界面上。

    C# 使用Get和Post请求获取数据

    总结来说,C#中的GET和POST请求是与服务器交互的基础,它们分别适用于不同的数据传输场景。GET请求用于获取信息,数据通过URL传递;而POST请求用于提交数据,数据包含在请求体中,适合传递大量或敏感信息。在C#的Web...

    C#通过HTTP协议get、post Webservice,并返回数据

    本教程将聚焦于如何利用C#通过HTTP协议执行GET和POST请求,与Webservice进行交互,并获取返回的数据。这对于构建客户端应用和服务端通信至关重要。 首先,让我们了解HTTP协议。超文本传输协议(HTTP)是互联网上...

    C#-HTTP请求(Post,GET,表单)

    C#-HTTP请求(Post,GET,表单)

    C#winform工具模拟getpost请求,app防攻击加密源码

    1,不知道咋get、post请求的; 2,写的接口总是被攻击的可以借鉴此加密方式。 【2】为啥要写这个 1,近期我们团队做的App接口被破解,老是被频繁调用,服务器致瘫; 2,想了办法加密了,如果遇到问题想调试,没办法...

    C# 后台请求接口的方法(GET,POST)

    通过上述代码示例可以看出,无论是GET还是POST请求,在C#中都可以通过`System.Net`提供的API进行实现。开发者可以根据实际需求选择合适的请求方式。需要注意的是,对于安全性要求较高的场景,建议使用POST请求;而...

    C#-HTTP请求接收(Post数据流,GET,表单)

    C#-HTTP请求接收(Post数据流,GET,表单)

    实现HTTP协议中的GET、POST请求

    实现HTTP协议中的GET、POST请求

    C#后台 Get、Post 网络请求

    C#后台 Get、Post 网络请求 获取网页信息--可以做到一个文件多出使用(后台结果公告内容,通过获取结果公告内容抓取到前台显示) 微信公众平台调用post提交数据 有些需要传递json格式的数据如果不是json格式的数据...

    C#实现发送简单HTTP请求的方法

    除了上述基本的GET请求,C#还支持POST请求,常用于向服务器提交数据。要发送POST请求,你需要设置WebRequest对象的一些额外属性,例如: ```csharp req.Method = "POST"; req.ContentType = "application/x-...

    自己封装的C#实现HTTP请求的动态链接库,dll

    标题中的“自己封装的C#实现HTTP请求的动态链接库,dll”指的是使用C#编程语言编写的HTTP客户端库,该库被封装成一个动态链接库(DLL)文件,供其他应用程序调用,以实现HTTP协议的网络通信功能。DLL是一种可重用的...

    C# Http Post Get

    在 C# 编程语言中,根据 HTTP 协议创建 GET 和 POST 方式的 HTTP 请求是一项基本且重要的技能。以下是对如何使用 C# 创建这两种请求的具体介绍。 #### 一、理解 HTTP GET 请求 GET 请求通常用于获取资源的信息,...

    Api接口调用封装,实现POSt,GET等数据请求

    Api接口调用封装,实现POSt,GET等数据请求,Api接口调用封装,实现POSt,GET等数据请求,Api接口调用封装,实现POSt,GET等数据请求,Api接口调用封装,实现POSt,GET等数据请求,Api接口调用封装,实现POSt,GET等数据请求,...

    C# WebService 客户端 服务器 Get Post

    总结,C# WebService客户端和服务器之间的通信是通过HTTP协议的GET和POST方法进行的,这使得跨平台、跨语言的数据交换变得简单。在实际开发中,理解并熟练运用这些知识能够帮助我们构建高效、安全的分布式系统。

Global site tag (gtag.js) - Google Analytics