C#发起http的GET/POST请求并处理响应,及其函数封装

HTTP请求需要引入的命名空间

using System.Net;

1、先整个窗体

       我会先些一个命令行程序分别实现GET请求和POST请求,这是最终的窗体程序。

        如下:

  •          url输入框用来获取要发起的http请求的地址
  •          GET/POST 单选框用来选择发起的http请求的方式
  •          选择post方式的时候,需要在输入文本框输入内容
  •          点击连接按钮发起请求
  •          发起请求后获得的响应会显示到响应文本框

2、设置一下服务器

        用nodejs实现的服务器逻辑,用PHP更方便。

var _http = require('http');
var _query = require('querystring');

var server = _http.createServer(function (req, res) {
    res.writeHead(200, {"Content-Type": 'text/html;charset=utf-8'});
	let obj;
    
    //如果请求方式是POST
	if(req.method == "POST"){
		var buff = '';
        //监控响应内容
		req.on('data', (data) => {
			buff += data;
		});
		req.on('end', () => {
			obj = _query.parse(buff);
			var a = 'POST 方式的请求,请求内容:'+JSON.stringify(obj);

            //把 a 作为响应的数据返回给请求方。
			res.end(a);
		});

	}
	if(req.method == "GET"){
        //把url里的query字符串(a=abc&b=bbb)解析成对象obj
		obj = _query.parse(req.url);
		var a = 'GET 方式的请求,请求内容:'+JSON.stringify(obj);

        //把 a作为响应的数据返回给请求方。
		res.end(a);
	}
     //把 a 显示到命令行
	console.log(a);
});
//服务器端口设置为3001
server.listen(3001, function () {
    console.log('服务器创建成功!port:3001');
});

3、实现http GET请求

//请求的http地址
string url = "http://localhost:3001/qq?a=abc&b=bbb";

//预备请求的资源
HttpWebRequest request = null;
HttpWebResponse response = null;
StreamReader reader = null;

string content = string.Empty;

try
{
    //实例化一个http请求
    request = (HttpWebRequest)WebRequest.Create(url);
    //设置请求头 请求方式method=get
    request.Method = "GET";

    //使request。getResponse()返回的一个响应对象
    response = (HttpWebResponse)request.GetResponse();
    //reader 读取响应流
    using (reader = new StreamReader(response.GetResponseStream()))
    {
        //意思是从头读到尾,全部读完
       content = reader.ReadToEnd();
    }
}
catch (System.Exception err)
{
    Console.WriteLine("1.GET出现了错误!\n错误来源:" + err.Source + "错误信息:" + err.Message);
}
Console.WriteLine("响应:" + content);
//为啥read大家都懂
Console.Read();

          

        看一下效果:

输出符合预期,显然代码是可行。

4、接下来实现的是post请求

//请求的http地址
string url = "http://localhost:3001/qq?a=abc&b=bbb";
//要发送的数据
string msg = "method is post.";

//预备请求的资源
HttpWebRequest request = null;
HttpWebResponse response = null;
//post请求需要一个流把数据写进去
Stream requestStream = null;
StreamReader reader = null;

//request所携带的数据是字节码,所以msg需要转化为byte[]数组才能读入
var data = Encoding.UTF8.GetBytes(string.Format("a={0}&b={1}", "message", msg));
string content = string.Empty;

try
{
    //实例化一个http请求
    request = (HttpWebRequest)WebRequest.Create(url);
    //设置请求头 请求方式method=post
    request.Method = "POST";

    //请求类型
    request.ContentType = "application/text";
    
    requestStream = request.GetRequestStream();
    requestStream.Write(data, 0, data.Length);

     response = (HttpWebResponse)request.GetResponse();
    //reader 读取响应流
     using (reader = new StreamReader(response.GetResponseStream()))
    {
        content = reader.ReadToEnd();
    }
}
 catch (System.Exception err)
{
    Console.WriteLine("1.POST出现了错误!\n错误来源:" + err.Source + "错误信息:" + err.Message);
}

Console.WriteLine("响应:" + content);
Console.Read();

         输出:

5、封装成函数

       封装的函数已经可以直接使用了。

        首先是GET请求:

        /// <summary>
        /// GET方式发送得结果
        /// </summary>
        /// <param name="url">请求的url</param>
        /// <returns>服务器响应的数据</returns>
        public static string getHttpRequest(string url)
        {
            //预备请求的资源
            HttpWebRequest request = null;
            HttpWebResponse response = null;
            StreamReader reader = null;

            string content = string.Empty;

            try
            {
                request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "GET";

                response = (HttpWebResponse)request.GetResponse();
                using (reader = new StreamReader(response.GetResponseStream()))
                {
                    content = reader.ReadToEnd();
                }
            }
            catch (System.Exception err)
            {
                MessageBox.Show("1.GET出现了错误!\n错误来源:" + err.Source + "\n错误信息:" + err.Message+"\n"+err);
                Console.WriteLine("1.GET出现了错误!\n错误来源:" + err.Source + "错误信息:" + err.Message);
            }

            //用完销毁
            response.Dispose();
            reader.Dispose();

            return content;
        }

        然后是POST方式:

        /// <summary>
        /// 发起一个http请求,方式为POST
        /// </summary>
        /// <param name="uri">发送请求的目标url</param>
        /// <param name="reMsg">要发送的消息</param>
        /// <returns>服务器响应的数据</returns>
        public string postHttpRequest(string uri, string msg)
        {
            //预备请求的资源
            HttpWebRequest request = null;
            HttpWebResponse response = null;
            Stream requestStream = null;
            StreamReader reader = null;

            var data = Encoding.UTF8.GetBytes(string.Format("a={0}&b={1}", "message", msg));
            string content = "";

            try
            {    
                request = (HttpWebRequest)WebRequest.Create(uri);
                request.Method = "POST";
                requestStream = request.GetRequestStream();

                request.ContentType = "application/text";

                requestStream.Write(data, 0, data.Length);
                response = (HttpWebResponse)request.GetResponse();

                using (reader = new StreamReader(response.GetResponseStream()))
                {
                    content = reader.ReadToEnd();
                }
            }
            catch (Exception err) {
                MessageBox.Show("1.POST出现了错误!\n错误来源:" + err.Source + "\n错误信息:" + err.Message + "\n" + err);
                Console.WriteLine("1.POST出现了错误!\n错误来源:" + err.Source + "错误信息:" + err.Message);
            }

            //资源用完回收
            requestStream.Dispose();
            response.Dispose();
            reader.Dispose();

            return content;
        }

       注意事项

        这里需要注意的是,封装后我加了几段销毁资源的代码。这个http请求方法我原本是用来进行一个课设项目的:本地程序 APP 监控一个温度感应器,每500毫秒就通过串口获取感应器的温度信息,然后通过http轮询把温度数据发送给服务器。

        但是在给老师演示的时候,演示的时间长了点,这个APP的后台内存占用五分钟飙升了600MB。

        后来看了一下微软的C#文档,原因是C#的垃圾回收机制 C#的垃圾回收机制 | 微软文档 ,用人能看懂的话描述就是:C#的垃圾回收器会不断遍历内存,查看哪些内存不再使用的,就打上标记,每隔一段时间回收一次被标记的内存

        但是在我发起的http请求中,我使用了reader读取响应流,却没有关闭它。让垃圾回收器以为这些资源还在使用,所以没有被回收造成了内存堆积。于是如果使用上面的方法进行http轮询,就需要手动回收内存。

6、在窗体程序中演示       

         GET方式:

        POST方式:

        下面是窗体程序的完整代码: 

using System;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;

namespace CSharp_http
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnConnec_Click(object sender, EventArgs e)
        {
            if (rabPOST.Checked && (txtSend.Text == "" || txtSend.Text == null))
            {
                MessageBox.Show("POST方式进行请求请输入信息");
                txtSend.Focus();
            }
            else {
                if (rabGET.Checked)
                {
                    //如果是get请求方式
                    txtRecive.Text = getHttpRequest(txtURL.Text.Trim());
                }
                else { 
                    //如果是post请求方式
                    txtRecive.Text = postHttpRequest(txtURL.Text.Trim(),txtSend.Text);
                }
            }
           
        }




        /// <summary>
        /// GET方式发送得结果
        /// </summary>
        /// <param name="url">请求的url</param>
        /// <returns>服务器响应的数据</returns>
        public static string getHttpRequest(string url)
        {
            //预备请求的资源
            HttpWebRequest request = null;
            HttpWebResponse response = null;
            StreamReader reader = null;

            string content = string.Empty;

            try
            {
                request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "GET";

                //hwRequest.Timeout = 30000;
                //hwRequest.ContentType = "application/text";

                response = (HttpWebResponse)request.GetResponse();
                using (reader = new StreamReader(response.GetResponseStream()))
                {
                    content = reader.ReadToEnd();
                }
            }
            catch (System.Exception err)
            {
                MessageBox.Show("1.GET出现了错误!\n错误来源:" + err.Source + "\n错误信息:" + err.Message+"\n"+err);
                Console.WriteLine("1.GET出现了错误!\n错误来源:" + err.Source + "错误信息:" + err.Message);
            }

            //用完销毁
            response.Dispose();
            reader.Dispose();

            return content;
        }

        /// <summary>
        /// 发起一个http请求,方式为POST
        /// </summary>
        /// <param name="uri">发送请求的目标url</param>
        /// <param name="reMsg">要发送的消息</param>
        /// <returns>服务器响应的数据</returns>
        public string postHttpRequest(string uri, string msg)
        {
            //预备请求的资源
            HttpWebRequest request = null;
            HttpWebResponse response = null;
            Stream requestStream = null;
            StreamReader reader = null;

            var data = Encoding.UTF8.GetBytes(string.Format("a={0}&b={1}", "message", msg));
            string content = "";

            try
            {    
                request = (HttpWebRequest)WebRequest.Create(uri);
                request.Method = "POST";
                requestStream = request.GetRequestStream();

                request.ContentType = "application/text";

                requestStream.Write(data, 0, data.Length);
                response = (HttpWebResponse)request.GetResponse();

                using (reader = new StreamReader(response.GetResponseStream()))
                {
                    content = reader.ReadToEnd();
                }
            }
            catch (Exception err) {
                MessageBox.Show("1.POST出现了错误!\n错误来源:" + err.Source + "\n错误信息:" + err.Message + "\n" + err);
                Console.WriteLine("1.POST出现了错误!\n错误来源:" + err.Source + "错误信息:" + err.Message);
            }

            //资源用完回收
            requestStream.Dispose();
            response.Dispose();
            reader.Dispose();

            return content;
        }
    }
}

PS:整个窗体小程序的解决方案我打包上传了,有兴趣的可以下载来康康

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值