win8/Metro开发系八 win8 开发之http协议浅析

由于最近我一直在忙着准备找工作和备考考试状态中,所以间断了没有更新,刚考完所以把这个项目连续更新完毕!抛砖引玉,希望大家能得到一点启发!不喜勿骂谢谢~!如果有交流的和找到的欢迎大家m我谢谢!

导读:在win8开发中属于移动开发,程序偏小所以业务逻辑一般不再程序中体验,一般都是从服务端获取数据做一个简单的绑定来展示数据,所以学会webserver是开发程序获取想要的数据源的必要,当然有些不提供接口,我们也可以把想要的数据获取出来,那就是分析数据包然后模拟浏览器发包取得数据,虽然这种方法有种不劳而获的不道德但是也不失为一种直接暴力有效的方法,接下来本节将和大家一起探讨一下简单的从web获取需要的数据的一些方法!

原理:

一、HTTP协议的简介

HTTP中文为超文本传输协议,从名字上很容易理解,Http协议就是将超文本标记语言的文档(即Html文档)从web服务传送到客户端的浏览器。它属于一个应用层的协议。

二、网络的工作过程

当用户要访问网络中的某个网页时,大致要经过以下几个步骤:

1.用户首先要确定网页文件所在的URL(统一资源定位符,也就是网页在网络上的家庭住址,通过这个地址就可以找到这个网页)如www.cnblogs.com

2.浏览器向DNS(域名服务器)发出请求,告诉DNS说:"我要把www.cnblogs.com转化为它所定义的IP地址",这里可以简单把DNS理解为一个字典,知道域名就可以知道域名对于的IP地址,他们有这个一个映射的关系

3.DNS收到请求后就开始查询,查到后向浏览器返回结果。如域名为www.cnblogs.com对应的IP地址为61.155.169.116

4.知道IP地址后, 浏览器向IP地址为61.155.169.116的主机发出与端口号80建议一条TCP连接请求(HTTP协议是建立在传输层TCP的基础上的),80端口是服务器提供web服务的默认端口

5.建立连接后,浏览器发出一条HTTP请求,如 GET http://www.cnblogs.com/ HTTP/1.1

6.当域名为www.cnblogs.com的服务器接受到请求后,向浏览器发送一个html文件

7.文件发送完后,由服务器主动关闭TCP连接。

8.浏览器接收传送来的页面并显示

9.如果Html文件中包含图片,还要与服务器再次建立一个TCP连接,以便可以下载图片

上面介绍的步骤中,浏览器发出一个请求后,如何把一个服务器上的HTML文档下载到请求网页的主机上呢? 这个过程就是由HTTP完成,即完成超文本文件的传送,HTTP协议是web服务器的基础。

二、HTTP请求

Http请求由三部分组成:请求行、请求头和请求数据,一个HTTP请求的格式一般如下:

 

 请求方法 URL HTTP版本号 
请求头信息 
 <一个空行> 
请求数据

 

HTTP请求的方法如下表:

经常使用的是Get和Post方法,当使用Get方法发出请求时,请求数据为空,所以此时的HTTP请求行就由两部分组成:请求行和请求头信息,下面我们形象看看具体的HttP的实例:

当在浏览器中地址栏里面输入:www.cnblogs.com,此时我们相当于发出一个HTTP请求,具体为:

并且从图中可以看出网页中含有图片脚本等文件时,客户端会继续与服务器发出请求,请求所需要的图片和脚本文件。

补充:经一位朋友的留言中,在这里我补充下,现在通常是只建立一个TCP连接,通过HTPP 请求头的Connetion字段来指明,当服务器收到附带有Connection: Keep-Alive的请求时,它也会在响应头中添加一个同样的字段来使用Keep-Alive。这样一来,客户端和服务器之间的HTTP连接就会被保持,不会断开,(一些特殊情况除外)当客户端发送另外一个请求时,就使用这条已经建立的连接。

下面介绍下请求头的信息:

Accept:表示客户端接收的数据类型。例如,Accept:text/html表示客户端可接收HTML类型的文本

User Agent:表示客户端软件类型

Referer:表示的是上一连接的url,如跳转到本页面的上一页面url。

上图是一个通过Get方法把一个HTML文件下载到本例浏览器中显示的过程,当我们在博客园主页面点登陆后输入用户名和密码后点确认按钮后,此时我们发出的HTTP的请求是通过Post方法,下面是一个截图:

从图中可以看出, 通过Post方法发出的HTTP请求中有一个空行(空行后为请求数据),而Get方法发出的请求中没有。

三、HTTP响应

同样,Http响应也是由三部分组成:状态行,响应头和响应数据组成,Http响应格式如下:

 

 状态行 
响应头 
<一个空行> 
响应数据

 

状态行以HTTP版本号开始,后面跟着3为数字,代表响应代码,响应代码用来告诉客户端,服务器是否产生了预期的响应。如HTTP/1.1 200 OK.

HTTP/1.1中定义五种响应代码:

1xx:指示信息--表示请求已接收,继续处理

2xx:成功--表示请求已被成功接收、理解、接受

3xx:重定向--要完成请求必须进行更进一步的操作

4xx:客户端错误--请求有语法错误或请求无法实现

5xx:服务器端错误--服务器未能实现合法的请求

具体响应代码的说明见下:

HTTP响应头用于服务器向客户端提供请求文档信息或服务端的状态信息,如图

四、总结

到这里这篇文章也算是说完了,HTTP协议只是应用层中协议的其中之一,应用层还有其他的一些协议,比如FTP(文件传输协议),SMTP(电子邮件协议)等,这些协议在后面都会有所介绍。后面一个专题打算应用HTTP协议的只是自定义一个简单的Web服务器来模拟我们平常在浏览器中输入网址后发送Http请求和服务器返回响应的过程。

以上基本知识大家如果没接触过可以看看原文出处http://www.cnblogs.com/zhili/archive/2012/08/18/HTTP.html

win8中封装到httpclient这个类

用法很简单get post就ok但是有一些头痛的问题比较让人惆怅接下来就给出简单的示例代码然后从一些常见的问题来详细说明他的用法!!

get:

这是一个发包解码的代码发一get请求,得到服务器返回解码后的数据

View Code
1  Char[] c = input.ToCharArray();
2             HttpClient wc = new HttpClient(new MyHttpHeaders());
3           //  Windows.Data.Html.HtmlUtilities.
4             string urlData=await wc.GetStringAsync("http://www1.nuc.edu.cn/gonghui/Handler.ashx?url="+c[0]);

post:

View Code
HttpContent PostContent = new StreamContent(stream);
            PostContent.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("multipart/form-data; boundary=" + boundary);
 
            HttpClient client = new HttpClient();
            HttpResponseMessage response = await client.PostAsync("接口地址", PostContent);

当然还有很多的方法这里就不详细的说明了,我在使用的过程中大致遇到了那么写方法

第一:中文问题,这个问题直接导致的结果就是乱码

1.url编码问题:url中出现中文直接导致发包发送的url失败,url常会使用utf-8编码和gb2312简体中文国标码

  win8默认的send函数有utf-8自动编码功能所以不用你去问,直接发送即可,但gb2312就需要你来对其进行编码处理了,呵呵不才到现在我还没找到怎么编码所以用net2.0里的urlencoding在服务器上进行编码然后用Get请求发送需要编码的数据然后得到编码后的结果!!如果有谁知道怎么编码告诉小弟呵呵谢谢

2.接手的responsed数据编码问题,这我记得也是默认的utf-8,如果乱码可以解码成

View Code
if (string.IsNullOrEmpty(contentType.CharSet))
            {
                contentType.CharSet = "gb2312";
            }

第二:响应内容过长导致HttpRequestException

HttpClient有一个属性MaxResponseContentBufferSize,它表示的是读取响应内容时最大字节数缓冲区。它的默认值是64k,当页面内容很多,超过64k的时候,就会抛出一个HttpRequestException,导致Get失败。

View Code
1  HttpClient client = new HttpClient() { MaxResponseContentBufferSize = 1024 * 1024 }; 

还有就是可能在请求过程中,遇到防盗等问题,这些问题可能会导致你请求失败,把你重定向到一个错误页面导致你的请求得不到想要的数据

比如:referer  userAgent,上面基础已经介绍自己可以看看

请求来源和请求客户端,httpclient爬取网页可能服务器会反爬虫,不让你采集

遇到这种情况需要你自己像报文头添加请求信息

具体的信息用浏览器抓包的看是什么信息然后自定义一下报文头来绕过验证获取真正的信息

并且还可以再自定义报文头加入很多其他东西例如cookie等信息

代码:

View Code
class MyHttpHeaders:HttpClientHandler

    {
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            //request.Headers.Referrer = new Uri("http://www.google.com/");
            request.Headers.Add("UserAgent", "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.92 Safari/537.4");
            var rsponse = await base.SendAsync(request, cancellationToken);
            var contentType = rsponse.Content.Headers.ContentType;
            if (string.IsNullOrEmpty(contentType.CharSet))
            {
                contentType.CharSet = "gb2312";
            }
            return rsponse;

        }

应用这个报文头

1  Char[] c = input.ToCharArray();
2             HttpClient wc = new HttpClient(new MyHttpHeaders());
3           //  Windows.Data.Html.HtmlUtilities.
4             string urlData=await wc.GetStringAsync("http://www1.nuc.edu.cn/gonghui/Handler.ashx?url="+c[0]);
5             string url = "http://www.baidu.com?font="+urlData;
6             string w = await wc.GetStringAsync(url);
7             return w;

 

 

 

 

posted @ 2012-11-09 15:02  ~星~  阅读(1951)  评论(0编辑  收藏  举报