谈到HTTP协议(超文本传输协议),HTTP协议是一个基于请求与响应模式的、无状态的、应用层的协议,常基于TCP的连接方式,HTTP1.1版本中给出一种持续连接的机制,绝大多数的Web开发,都是构建在HTTP协议之上的Web应用。

HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。HTTP协议的主要特点可概括为:1.支持客户/服务器模式。2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。3.灵活:HTTP允许传输任意类型的数据对象。4.无连接:无连接的含义是限制每次连接只处理一个请求。5.无状态:HTTP协议是无状态协议。

在.NET框架里面对HTTP协议的处理主要采用WebRequest对象,在我们的.NET项目中如果需要生成HTTP请求或者处理HTTP请求,会运用HttpWebRequest和HttpWebResponse对象。在实际项目的开发中,有一些需求需要同地方平台进行数据交互,例如我们经常使用的微信,支付宝,QQ等等平台,这就需要我们在自己的项目中生成对应的HTTP请求和处理相关HTTP请求信息。

如何在我们的系统中后台生成对应的HTTP请求,这个事情就需要对HTTP协议做一个简单的了解:

HTTP请求由三部分组成,分别是:请求行、消息报头、请求正文。HTTP响应也是由三个部分组成,分别是:状态行、消息报头、响应正文。HTTP消息由客户端到服务器的请求和服务器到客户端的响应组成。请求消息和响应消息都是由开始行(对于请求消息,开始行就是请求行,对于响应消息,开始行就是状态行),消息报头(可选),空行(只有CRLF的行),消息正文(可选)组成。

现在提供一个较为通用的处理HTTP请求的代码,此部分主要是生成同步HTTP请求。

在谈到.NET的同步中,需要介绍一下同步和异步的相关内容:

同步,可以理解为在执行完一个函数或方法之后,一直等待系统返回值或消息,这时程序是出于阻塞的,只有接收到返回的值或消息后才往下执行其他的命令。

异步,执行完函数或方法后,不必阻塞性地等待返回值或消息,只需要向系统委托一个异步过程,那么当系统接收到返回值或消息时,系统会自动触发委托的异步过程,从而完成一个完整的流程。

(以上的图都是从别处截的,感谢提供资料的博主们。)

现在直接给出相关代码:

         /// <summary>
/// 访问次数字典
/// </summary>
private readonly ConcurrentDictionary<string, int> _urlTryList = new ConcurrentDictionary<string, int>();
       /// <summary>
/// Post数据
/// </summary>
public String PostData { set; private get; }
        /// <summary>
/// 同步请求
/// </summary>
/// <param name="url">请求地址</param>
/// <param name="tryTimes">错误重试次数</param>
public string SyncRequest(string url, int tryTimes = )
{
if (string.IsNullOrEmpty(url))
{
throw new ArgumentNullException(url);
}
Trace.TraceInformation(string.Concat("开始同步请求:", url));
_urlTryList.TryAdd(url, tryTimes);
//创建并定义HTTP请求相关信息
var request = WebRequest.Create(url) as HttpWebRequest;
if (request == null) return string.Empty;
request.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");
request.Headers.Add("Accept-Language", "zh-CN,zh;q=0.8");
request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate | DecompressionMethods.None;
request.Credentials = CredentialCache.DefaultNetworkCredentials;
request.UseDefaultCredentials = false;
request.KeepAlive = false;
request.PreAuthenticate = false;
request.ProtocolVersion = HttpVersion.Version10;
request.UserAgent =
"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36";
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
request.Timeout = * * ;
request.CookieContainer = CookieContainer;
request.AllowAutoRedirect = true;
//判断POST请求是否为空
if (!string.IsNullOrEmpty(PostData))
{
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
using (var postStream = request.GetRequestStream())
{
var byteArray = Encoding.GetBytes(PostData);
postStream.Write(byteArray, , PostData.Length);
postStream.Close();
}
}
else
{
request.AllowWriteStreamBuffering = false;
}
try
{
using (var response = request.GetResponse() as HttpWebResponse)
{
if (response != null)
{
if (response.StatusCode != HttpStatusCode.OK)
{
Trace.TraceError(string.Concat("请求地址:", request.RequestUri, " 失败,HttpStatusCode",
response.StatusCode));
return string.Empty;
}
using (var streamResponse = response.GetResponseStream())
{
if (streamResponse != null)
{
if (!IsText(response.ContentType))
{
var contentEncodingStr = response.ContentEncoding;
var contentEncoding = Encoding;
if (!string.IsNullOrEmpty(contentEncodingStr))
contentEncoding = Encoding.GetEncoding(contentEncodingStr);
var streamRead = new StreamReader(streamResponse, contentEncoding);
var str = streamRead.ReadToEnd();
if (CallBackAction != null && !String.IsNullOrEmpty(str))
CallBackAction.BeginInvoke(str, request.RequestUri.ToString(), (s) => { }, null);
return str;
}
//创建并指定文件夹
var fileName = string.Concat(DateTime.Now.ToString("yyyyMMdd"), "/", DateTime.Now.ToString("yyyyMMddHHmmssffff"),
Path.GetExtension(request.RequestUri.AbsoluteUri));
var fileDirectory = Path.Combine(FileSavePath, DateTime.Now.ToString("yyyyMMdd"));
if (!Directory.Exists(fileDirectory))
Directory.CreateDirectory(fileDirectory);
try
{
//下载文件
using (var fileStream = new FileStream(Path.Combine(FileSavePath, fileName), FileMode.Create))
{
var buffer = new byte[];
int readLength;
do
{
readLength = streamResponse.Read(buffer, , buffer.Length);
fileStream.Write(buffer, , readLength);
} while (readLength != );
}
if (CallBackAction != null && !String.IsNullOrEmpty(fileName))
CallBackAction.BeginInvoke(fileName, request.RequestUri.ToString(), (s) => { }, null);
return fileName;
}
catch (IOException ex)
{
throw new IOException(ex.Message, ex);
}
}
}
response.Close();
}
}
}
catch (WebException ex)
{
Trace.TraceError(string.Concat("请求地址:", request.RequestUri, " 失败信息:", ex.Message));
var toUrl = request.RequestUri.ToString();
if (_urlTryList.TryGetValue(toUrl, out tryTimes))
{
_urlTryList.TryUpdate(toUrl, tryTimes, tryTimes - );
if (tryTimes - <= )
{
_urlTryList.TryRemove(toUrl, out tryTimes);
Trace.TraceError(string.Concat("请求地址重试失败:", request.RequestUri));
return string.Empty;
}
SyncRequest(toUrl);
}
}
finally
{
request.Abort();
}
return string.Empty;
}

以上就是对相关概念和代码的解析。有写的不到位的地方,敬请谅解。

HTTP在.NET中的一些应用和解析的更多相关文章

  1. 前端开发:Javascript中的数组,常用方法解析

    前端开发:Javascript中的数组,常用方法解析 前言 Array是Javascript构成的一个重要的部分,它可以用来存储字符串.对象.函数.Number,它是非常强大的.因此深入了解Array ...

  2. JS中parseInt()、Numer()深度解析

    JS中字符串转换为数字有两种方式: 1.parseInt函数 定义:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/ ...

  3. Scala 深入浅出实战经典 第65讲:Scala中隐式转换内幕揭秘、最佳实践及其在Spark中的应用源码解析

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  4. Scala 深入浅出实战经典 第61讲:Scala中隐式参数与隐式转换的联合使用实战详解及其在Spark中的应用源码解析

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载: 百度云盘:http://pan.baidu.com/s/1c0noOt ...

  5. Scala 深入浅出实战经典 第60讲:Scala中隐式参数实战详解以及在Spark中的应用源码解析

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  6. Scala 深入浅出实战经典 第48讲:Scala类型约束代码实战及其在Spark中的应用源码解析

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  7. Android中的三种XML解析方式

    在Android中提供了三种解析XML的方式:SAX(Simple API XML),DOM(Document Objrect Model),以及Android推荐的Pull解析方式.下面就对三种解析 ...

  8. .NET中常用的几种解析JSON方法

    一.基本概念 json是什么? JSON:JavaScript 对象表示法(JavaScript Object Notation). JSON 是一种轻量级的数据交换格式,是存储和交换文本信息的语法. ...

  9. 转 web项目中的web.xml元素解析

    转 web项目中的web.xml元素解析 发表于1年前(2014-11-26 15:45)   阅读(497) | 评论(0) 16人收藏此文章, 我要收藏 赞0 上海源创会5月15日与你相约[玫瑰里 ...

  10. 【原创】Matlab中plot函数全功能解析

    [原创]Matlab中plot函数全功能解析 该帖由Matlab技术论(http://www.matlabsky.com)坛原创,更多精彩内容参见http://www.matlabsky.com 功能 ...

随机推荐

  1. LL LR SLR LALR 傻傻分不清

    [转] 一:LR(0),SLR(1),规范LR(1),LALR(1)的关系     首先LL(1)分析法是自上而下的分析法.LR(0),LR(1),SLR(1),LALR(1)是自下而上的分析法.   ...

  2. tableView:cellForRowAtIndexPath:方法中indexPath.row不是从0开始的,从4开始

    问题描述:重新刷新数据源,刷新列表时,发现前面4个cell没有显示出来,直接从第5条开始的,这是什么东东? 在tableView:numberOfRowsInSection:方法里打印数据源个数,是正 ...

  3. *HDU1850 博弈

    Being a Good Boy in Spring Festival Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32 ...

  4. 关于IOS浏览器:document,body的click事件触发规则

    今天做了个手机页面,点击某个按钮->弹出菜单,再点击菜单以外的任意位置->关闭菜单,在其他浏览器里面没有问题,但是在IOS浏览器中并不会关闭. 网上解决这个bug的帖子很多,这篇帖子主要是 ...

  5. Ionic实战 自动升级APP(Android版)

    Ionic 框架介绍 Ionic是一个基于Angularjs.可以使用HTML5构建混合移动应用的用户界面框架,它自称为是"本地与HTML5的结合".该框架提供了很多基本的移动用户 ...

  6. 爬虫初探(1)之urllib.request

    -----------我是小白------------ urllib.request是python3自带的库(python3.x版本特有),我们用它来请求网页,并获取网页源码. # 导入使用库 imp ...

  7. Spket在Eclipse下的安装和配置(图文教程)

    一.Spket简介 Spket是一个RIA的开发工具,具有代码自动完成.语法高亮.内容概要等功能,可以帮助开发人员高效的编写JavaScript程序. 效果图: 二.安装Spket 1.去官网(htt ...

  8. Second Day: 关于Button监听事件的三种方法(匿名类、外部类、继承接口)

    第一种:通过匿名类实现对Button事件的监听 首先在XML文件中拖入一个Button按钮,并设好ID,其次在主文件.java中进行控件初始化(Private声明),随后通过SetOnClickLis ...

  9. TaintDroid剖析之IPC级污点传播

    TaintDroid剖析之IPC级污点传播 作者:简行.走位@阿里聚安全 前言 在前三篇文章中我们详细分析了TaintDroid对DVM栈帧的修改,以及它是如何在修改之后的栈帧中实现DVM变量级污点跟 ...

  10. ABP理论学习之Web API控制器(新增)

    返回总目录 本篇目录 介绍 AbpApiController基类 本地化 审计日志 授权 工作单元 其他 介绍 ABP通过Abp.Web.ApiNuget包集成了 ASP.NET Web API控制器 ...