[深入浅出WP8.1(Runtime)]网络编程之HttpClient类

12.2 网络编程之HttpClient类

除了可以使用HttpWebRequest类来实现HTTP网络请求之外,我们还可以使用HttpClient类来实现。对于基本的请求操作,HttpClient类提供了一个简单的接口来处理最常见的任务,并为身份验证提供了适用于大多数方案的合理的默认设置。对于较为复杂的 HTTP 操作,更多的功能包括:执行常见操作(DELETE、GET、PUT 和 POST)的方法;获取、设置和删除 Cookie 的功能;支持常见的身份验证设置和模式;异步方法上提供的 HTTP 请求进度信息;访问有关传输的安全套接字层 (SSL) 详细信息;在高级应用中包含自定义筛选器的功能等。

12.2.1 Get请求获取字符串和数据流数据

(1)获取字符串数据

HttpClient类使用基于任务的异步模式提供了非常简化的请求操作,你可以直接调用HttpClient类GetStringAsync方法便可以获取到网络返回的字符串数据。下面我们来看一下使用Get请求来获取网络返回的字符串,实现的代码很简洁和简单,示例代码如下所示:

    Uri uri = new Uri("http://yourwebsite.com");

    HttpClient httpClient = new HttpClient();

    // 获取网络的返回的字符串数据

    string result = await httpClient.GetStringAsync (uri);

使用GetStringAsync方法是一种简化的HTTP请求,如果我们要获取到HTTP请求所返回的整个对象HttpResponseMessage类对象可以使用GetAsync方法。HttpResponseMessage对象是HTTP的相应消息对象,它包含了网络请求相应的HTTP头、数据体等信息。下面我们使用GetAsync方法来获取网络返回的字符串信息,示例代码如下所示:

    HttpResponseMessage response = await httpClient.GetAsync(uri);

    string responseBody = await response.Content.ReadAsStringAsync();

(2)获取数据流数据

HttpResponseMessage对象的Content属性表示是返回的数据对象,是一个IHttpContent类型的对象。如果要获取的是数据流数据,可以通过它的ReadAsBufferAsync方法获取到返回的IBuffer对象,或者通过ReadAsInputStreamAsync地方获取IInputStream对象,然后再转化为Stream对象,示例代码如下所示:

    using (Stream responseStream = (await response.Content.ReadAsInputStreamAsync()).AsStreamForRead())

    {

        int read = 0;

        byte[] responseBytes = new byte[1000];

        do

        {

            // 如果read等于0表示Stream的数据以及读取完毕

            read = await responseStream.ReadAsync(responseBytes, 0, responseBytes.Length);

        } while (read != 0);

    }

(3)取消网络请求

HttpClient类发起的网络请求都是基于任务的异步方法,所以要取消其异步的操作可以通过异步任务的取消对象CancellationTokenSource对象来取消,这点和HttpWebRequest类是不同。如果使用CancellationTokenSource对象来取消异步的请求会触发TaskCanceledException异常,这个异常需要我们用try catch语句来捕获,便可以识别到请求是被取消的。

    private CancellationTokenSource cts = new CancellationTokenSource();

    try

    {

        // 使用CancellationTokenSource对象来控制异步任务的取消操作

        HttpResponseMessage response = await httpClient.GetAsync(new Uri(resourceAddress)).AsTask(cts.Token);

        responseBody = await response.Content.ReadAsStringAsync().AsTask(cts.Token);

        cts.Token.ThrowIfCancellationRequested();

    }

    catch (TaskCanceledException)

    {

        responseBody = "请求被取消";

    }

    // 调用Cancel方法取消网络请求

    if (cts.Token.CanBeCanceled)

    {

        cts.Cancel();

    }

12.2.2 Post请求发送字符串和数据流数据

使用HttpClient类发起Post请求的编程方式也很简洁,我们可以调用方法PostAsync(Uri uri, IHttpContent content)来直接向目标的地址Post数据,在该方法里面有两个参数其中uri就是网络的目标地址,两外一个content是指你要向目标地址Post的数据对象。在Post数据之前我们首先把我们的数据初始化成为一个IHttpContent对象,那么实现了IHttpContent接口的类有HttpStringContent类、HttpStreamContent类和HttpBufferContent类,这三个类分表代表了字符串类型、数据流类型和二进制类型,那么数据流类型和二进制类型是可以互相转换的区别不大。调用PostAsync方法之后会返回一个HttpResponseMessage对象,通过这个HTTP的相应消息对象我们就可以获取Post请求之后的返回的结果信息。Post请求发送字符串和数据流数据的代码示例如下所示:

(1)Post请求发送字符串数据

    HttpStringContent  httpStringContent = new HttpStringContent("hello Windows Phone");

    HttpResponseMessage response = await httpClient.PostAsync(uri,

                                           httpStringContent).AsTask(cts.Token);

    string responseBody = await response.Content.ReadAsStringAsync().AsTask(cts.Token);

(2)Post请求发送数据流数据

    HttpStreamContent streamContent = new HttpStreamContent(stream.AsInputStream());

    HttpResponseMessage response = await httpClient.PostAsync(uri,

                                           streamContent).AsTask(cts.Token);

    string responseBody = await response.Content.ReadAsStringAsync().AsTask(cts.Token);

除了使用PostAsync方法之外,我们还可以使用SendRequestAsync方法来发送网络请求,SendRequestAsync方法既可以使用Get方式也可以使用Post方式。SendRequestAsync方法发送的消息类型是HttpRequestMessage类对象,HttpRequestMessage类表示HTTP的请求消息类,你可以通过HttpRequestMessage对象设置请求的类型(Get/Post)和传输的数据对象。使用SendRequestAsync方法的代码示例如下所示:

    // 创建HttpRequestMessage对象

    HttpStreamContent streamContent = new HttpStreamContent(stream.AsInputStream());

    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, new Uri(resourceAddress));

    request.Content = streamContent;

    // 发送数据

    HttpResponseMessage response = await httpClient.SendRequestAsync(request).AsTask(cts.Token);

    string responseBody = await response.Content.ReadAsStringAsync().AsTask(cts.Token);

12.2.3 设置和获取Cookie

Cookie是指某些网站为了辨别用户身份、进行回话跟踪而储存在用户本地终端上的数据(通常经过加密)。那么当我们在使用HTTP请求的时候,如果服务器返回的数据待用Cookie数据,我们也是可以获取出来,存储在本地,下次发起HTTP请求的时候就会带上这些Cookie的数据。

在HttpClient类的网络请求中我们可以通过HttpBaseProtocolFilter类来获取网站的Cookie信息,HttpBaseProtocolFilter类表示是HttpClient的HTTP请求的基础协议的过滤器。获取Cookie的代码示例如下所示:

    // 创建一个HttpBaseProtocolFilter对象

    HttpBaseProtocolFilter filter = new HttpBaseProtocolFilter();

    // 通过HttpBaseProtocolFilter对象获取使用HttpClient进行过网络请求的地址的Cookie信息

    HttpCookieCollection cookieCollection = filter.CookieManager.GetCookies(new Uri(resourceAddress));

    // 遍历整个Cookie集合的Cookie信息

    foreach (HttpCookie cookie in cookieCollection)

    {

    }

当然我们在发送HTTP请求的时候也一样可以带上Cookie信息,如果服务器可以识别到Cookie信息那么就会通过Cookie信息来进行一些操作,比如Cookie信息信息带有用户名和密码的加密信息,那么就可以免去登陆的步骤。在HttpClient的网路请求里面HttpCookie类表示是一个Cookie对象,创建好Cookie对象之后通过HttpBaseProtocolFilter对象的CookieManager属性来设置Cookie,然后发送网络请求,这时候的网络请求就会把Cookie信息给带上。设置Cookie的代码示例如下所示:

    // 创建一个HttpCookie对象,"id"表示是Cookie的名称,"localhost"是主机名,"/"是表示服务器的虚拟路径

    HttpCookie cookie = new HttpCookie("id", "yourwebsite.com", "/");

    // 设置Cookie的值

    cookie.Value = "123456";

    // 设置Cookie存活的时间,如果设置为null表示只是在一个会话里面生效

    cookie.Expires = new DateTimeOffset(DateTime.Now, new TimeSpan(0, 1, 8));

    // 在过滤器里面设置Cookie

    HttpBaseProtocolFilter filter = new HttpBaseProtocolFilter();

    bool replaced = filter.CookieManager.SetCookie(cookie, false);

……接下来可以向"yourwebsite.com"远程主机发起请求

12.2.4 网络请求的进度监控

HttpClient的网络请求是支持进度监控,通过异步任务的IProgress<T>对象可以直接监控到HttpClient的网络请求返回的进度信息,返回的进度对象是HttpProgress类对象。在进度对象HttpProgress里面包含了下面的一些信息:Stage(当前的状态)、BytesSent(已发送的数据大小)、BytesReceived(已接收的数据大小)、Retries(重试的次数)、TotalBytesToSend(总共需要发送的数据大小)和TotalBytesToReceive(总共需要接收的数据大小)。网络请求进度监控的代码示例如下所示:

    // 创建IProgress<HttpProgress>对象

    IProgress<HttpProgress> progress = new Progress<HttpProgress>(ProgressHandler);

    // 在异步任务中加入进度监控

    HttpResponseMessage response = await httpClient.PostAsync(new Uri(resourceAddress), streamContent).AsTask(cts.Token, progress);

    // 进度监控的回调方法

    private void ProgressHandler(HttpProgress progress)

    {

        // 在这里可以通过progress参数获取到进度的相关信息

    }

本文来源于《深入浅出Windows Phone 8.1 应用开发》

WP8.1 Runtime文章列表:http://www.cnblogs.com/linzheng/p/3998037.html

源代码下载:http://vdisk.weibo.com/s/zt_pyrfNHb99O

欢迎关注我的微博@WP林政   微信公众号:wp开发(号:wpkaifa)

WP8.1技术交流群:372552293

时间: 2024-08-03 19:25:43

[深入浅出WP8.1(Runtime)]网络编程之HttpClient类的相关文章

[深入浅出WIndows 10]网络编程之HttpClient类

14.2 网络编程之HttpClient类 除了可以使用HttpWebRequest类来实现HTTP网络请求之外,还可以使用HttpClient类来实现.对于基本的请求操作,HttpClient类提供了一个简单的接口来处理最常见的任务,并为身份验证提供了适用于大多数方案的合理的默认设置.对于较为复杂的 HTTP 操作,更多的功能包括:执行常见操作(DELETE.GET.PUT 和 POST)的方法:获取.设置和删除 Cookie 的功能:支持常见的身份验证设置和模式:异步方法上提供的 HTTP

网络编程之HttpClient类(转)

12.2 网络编程之HttpClient类 除了可以使用HttpWebRequest类来实现HTTP网络请求之外,我们还可以使用HttpClient类来实现.对于基本的请求操作,HttpClient类提供了一个简单的接口来处理最常见的任务,并为身份验证提供了适用于大多数方案的合理的默认设置.对于较为复杂的 HTTP 操作,更多的功能包括:执行常见操作(DELETE.GET.PUT 和 POST)的方法:获取.设置和删除 Cookie 的功能:支持常见的身份验证设置和模式:异步方法上提供的 HTT

[深入浅出WP8.1(Runtime)]Socket编程之UDP协议

13.3 Socket编程之UDP协议 UDP协议和TCP协议都是Socket编程的协议,但是与TCP协议不同,UDP协议并不提供超时重传,出错重传等功能,也就是说其是不可靠的协议.UDP适用于一次只传送少量数据.对可靠性要求不高的应用环境.既然 UDP 是一种不可靠的网络协议,那么还有什么使用价值或必要呢?其实不然,在有些情况下UDP协议可能会变得非常有用.因为UDP具有TCP所望尘莫及的速度优势.虽然TCP协议中植入了各种安全保障功能,但是在实际执行的过程中会占用大量的系统开销,无疑使速度受

Windows Phone 8.1的网络编程之HttpWebRequest类

Windows Phone中有两个类可以实现HTTP协议的网络请求:HttpWebRequest类HttpClient类 前者适合处理简单的网络请求,后者对HTTP请求的支持更加强大,适合复杂的网络请求封装. 不过在此之前需要认识一个HTTP的两种请求方式:Get请求和Post请求. 两者的区别是:Get请求:从服务器上获取数据,通过URI提交数据,数据在URI中可以看到,同时提交的数据最多只 能有1024字节.Post请求:向服务器传送数据,通过写入数据流的方式提交,Post请求对于提交的数据

【转】JAVA网络编程之Socket用法

JAVA网络编程之Socket用法 分类: JAVA2012-08-24 15:56 710人阅读 评论(0) 收藏 举报 在客户/服务器通信模式中,客户端需要主动建立与服务器连接的Socket,服务器端收到客户端的连接请求,也会创建与客户端连接的Socket.Socket可以看做是通信连接两端的收发器,客户端和服务店都通过Socket来收发数据. 1.构造Socket public Socket() 通过系统默认类型的 SocketImpl 创建未连接套接字 public Socket(Str

linux网络编程之shutdown() 与 close()函数详解

linux网络编程之shutdown() 与 close()函数详解 参考TCPIP网络编程和UNP: shutdown函数不能关闭套接字,只能关闭输入和输出流,然后发送EOF,假设套接字为A,那么这个函数会关闭所有和A相关的套接字,包括复制的:而close能直接关闭套接字. 1.close()函数 [cpp] view plain copy print? <span style="font-size:13px;">#include<unistd.h> int 

java网络编程之UDP实例

package Socket; import java.net.DatagramPacket; import java.net.InetAddress; public class Dgram { public static DatagramPacket toDatagram(String s, InetAddress destIA, int destPort) { byte[] buf = new byte[s.length() + 1]; s.getBytes(0, s.length(), b

java网络编程之TCP实例

Dgram类 package Socket; import java.net.DatagramPacket; import java.net.InetAddress; public class Dgram { public static DatagramPacket toDatagram(String s, InetAddress destIA, int destPort) { byte[] buf = new byte[s.length() + 1]; s.getBytes(0, s.leng

扯谈网络编程之Tcp SYN flood洪水攻击

简介 TCP协议要经过三次握手才能建立连接: (from wiki) 于是出现了对于握手过程进行的攻击.攻击者发送大量的FIN包,服务器回应(SYN+ACK)包,但是攻击者不回应ACK包,这样的话,服务器不知道(SYN+ACK)是否发送成功,默认情况下会重试5次(tcp_syn_retries).这样的话,对于服务器的内存,带宽都有很大的消耗.攻击者如果处于公网,可以伪造IP的话,对于服务器就很难根据IP来判断攻击者,给防护带来很大的困难. 攻与防 攻击者角度 从攻击者的角度来看,有两个地方可以