1
在了解HTTP断点续传的原理之前,让我们先来了解一下HTTP协议,HTTP协议是一种基于tcp的简单协议,分为请求和回复两种。请求协议是由客户机(浏览器)向服务器(WEB SERVER)提交请求时发送报文的协议。回复协议是由服务器(web server),向客户机(浏览器)回复报文时的协议。请求和回复协议都由头和体组成。头和体之间以一行空行为分隔。
2
3
以下是一个请求报文与相应的回复报文的例子:
4
GET /image/index_r4_c1.jpg HTTP/1.1
5
Accept: */*
6
Referer: http://192.168.3.120:8080
7
Accept-Language: zh-cn
8
Accept-Encoding: gzip, deflate
9
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.0.3705)
10
Host: 192.168.3.120:8080
11
Connection: Keep-Alive
12
13
14
HTTP/1.1 200 OK
15
Server: Microsoft-IIS/5.0
16
Date: Tue, 24 Jun 2003 05:39:40 GMT
17
Content-Type: image/jpeg
18
Accept-Ranges: bytes
19
Last-Modified: Thu, 23 May 2002 03:05:40 GMT
20
ETag: "bec48eb862c21:934"
21
Content-Length: 2827
22
23
….
24
下面我们就来说说"断点续传",顾名思义,断点续传就是在上一次下载时断开的位置开始继续下载。
25
在HTTP协议中,可以在请求报文头中加入Range段,来表示客户机希望从何处继续下载。
26
27
28
比如说从第1024字节开始下载,请求报文如下:
29
30
31
GET /image/index_r4_c1.jpg HTTP/1.1
32
Accept: */*
33
Referer: http://192.168.3.120:8080
34
Accept-Language: zh-cn
35
Accept-Encoding: gzip, deflate
36
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.0.3705)
37
Host: 192.168.3.120:8080
38
Range:bytes=1024-
39
Connection: Keep-Alive
40
.NET中的相关类
41
42
明白了上面的原理,那么,我们来看看.NET FRAMEWORK中为我们提供了哪些类可以来做这些事。
43
44
完成HTTP请求
45
46
System.Net.HttpWebRequest
47
48
HttpWebRequest 类对 WebRequest 中定义的属性和方法提供支持,也对使用户能够直接与使用 HTTP 的服务器交互的附加属性和方法提供支持。
49
50
HttpWebRequest 将发送到 Internet 资源的公共 HTTP 标头值公开为属性,由方法或系统设置。下表包含完整列表。可以将 Headers 属性中的其他标头设置为名称/值对。但是注意,某些公共标头被视为受限制的,它们或者直接由 API公开,或者受到系统保护,不能被更改。Range也属于被保护之列,不过,.NET为开发者提供了更方便的操作,就是 AddRange方法,向请求添加从请求数据的开始处或结束处的特定范围的字节范围标头
51
52
完成文件访问
53
54
System.IO.FileStream
55
56
FileStream 对象支持使用Seek方法对文件进行随机访问, Seek 允许将读取/写入位置移动到文件中的任意位置。这是通过字节偏移参考点参数完成的。字节偏移量是相对于查找参考点而言的,该参考点可以是基础文件的开始、当前位置或结尾,分别由SeekOrigin类的三个属性表示。
57
58
代码实现
59
60
了解了.NET提供的相关的类,那么,我们就可以方便的实现了。
61
62
代码如下:
63
64
65
static void Main(string[] args)
66
{
67
68
string StrFileName="c:\\aa.zip"; //根据实际情况设置
69
string StrUrl="http://www.xxxx.cn/xxxxx.zip";; //根据实际情况设置
70
71
//打开上次下载的文件或新建文件
72
long lStartPos =0;
73
System.IO.FileStream fs;
74
if (System.IO.File.Exists(StrFileName))
75
{
76
fs= System.IO.File.OpenWrite(StrFileName);
77
lStartPos=fs.Length;
78
fs.Seek(lStartPos,System.IO.SeekOrigin.Current); //移动文件流中的当前指针
79
}
80
else
81
{
82
fs = new System.IO.FileStream(StrFileName,System.IO.FileMode.Create);
83
lStartPos =0;
84
}
85
86
//打开网络连接
87
try
88
{
89
System.Net.HttpWebRequest request =(System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(StrUrl);
90
if ( lStartPos>0)
91
request.AddRange((int)lStartPos); //设置Range值
92
93
//向服务器请求,获得服务器回应数据流
94
System.IO.Stream ns= request.GetResponse().GetResponseStream();
95
96
byte[] nbytes = new byte[512];
97
int nReadSize=0;
98
nReadSize=ns.Read(nbytes,0,512);
99
while( nReadSize >0)
100
{
101
fs.Write(nbytes,0,nReadSize);
102
nReadSize=ns.Read(nbytes,0,512);
103
}
104
fs.Close();
105
ns.Close();
106
Console.WriteLine("下载完成");
107
}
108
catch(Exception ex)
109
{
110
fs.Close();
111
Console.WriteLine("下载过程中出现错误:"+ex.ToString());
112
}
113
}
114
在了解HTTP断点续传的原理之前,让我们先来了解一下HTTP协议,HTTP协议是一种基于tcp的简单协议,分为请求和回复两种。请求协议是由客户机(浏览器)向服务器(WEB SERVER)提交请求时发送报文的协议。回复协议是由服务器(web server),向客户机(浏览器)回复报文时的协议。请求和回复协议都由头和体组成。头和体之间以一行空行为分隔。2

3
以下是一个请求报文与相应的回复报文的例子:4
GET /image/index_r4_c1.jpg HTTP/1.15
Accept: */*6
Referer: http://192.168.3.120:80807
Accept-Language: zh-cn8
Accept-Encoding: gzip, deflate9
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.0.3705)10
Host: 192.168.3.120:808011
Connection: Keep-Alive12

13

14
HTTP/1.1 200 OK15
Server: Microsoft-IIS/5.016
Date: Tue, 24 Jun 2003 05:39:40 GMT17
Content-Type: image/jpeg18
Accept-Ranges: bytes19
Last-Modified: Thu, 23 May 2002 03:05:40 GMT20
ETag: "bec48eb862c21:934"21
Content-Length: 282722

23
…. 24
下面我们就来说说"断点续传",顾名思义,断点续传就是在上一次下载时断开的位置开始继续下载。25
在HTTP协议中,可以在请求报文头中加入Range段,来表示客户机希望从何处继续下载。26

27

28
比如说从第1024字节开始下载,请求报文如下:29

30

31
GET /image/index_r4_c1.jpg HTTP/1.132
Accept: */*33
Referer: http://192.168.3.120:808034
Accept-Language: zh-cn35
Accept-Encoding: gzip, deflate36
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.0.3705)37
Host: 192.168.3.120:808038
Range:bytes=1024-39
Connection: Keep-Alive 40
.NET中的相关类41

42
明白了上面的原理,那么,我们来看看.NET FRAMEWORK中为我们提供了哪些类可以来做这些事。43

44
完成HTTP请求45

46
System.Net.HttpWebRequest47

48
HttpWebRequest 类对 WebRequest 中定义的属性和方法提供支持,也对使用户能够直接与使用 HTTP 的服务器交互的附加属性和方法提供支持。49

50
HttpWebRequest 将发送到 Internet 资源的公共 HTTP 标头值公开为属性,由方法或系统设置。下表包含完整列表。可以将 Headers 属性中的其他标头设置为名称/值对。但是注意,某些公共标头被视为受限制的,它们或者直接由 API公开,或者受到系统保护,不能被更改。Range也属于被保护之列,不过,.NET为开发者提供了更方便的操作,就是 AddRange方法,向请求添加从请求数据的开始处或结束处的特定范围的字节范围标头51

52
完成文件访问53

54
System.IO.FileStream55

56
FileStream 对象支持使用Seek方法对文件进行随机访问, Seek 允许将读取/写入位置移动到文件中的任意位置。这是通过字节偏移参考点参数完成的。字节偏移量是相对于查找参考点而言的,该参考点可以是基础文件的开始、当前位置或结尾,分别由SeekOrigin类的三个属性表示。57

58
代码实现59

60
了解了.NET提供的相关的类,那么,我们就可以方便的实现了。61

62
代码如下:63

64

65
static void Main(string[] args)66
{67

68
string StrFileName="c:\\aa.zip"; //根据实际情况设置69
string StrUrl="http://www.xxxx.cn/xxxxx.zip";; //根据实际情况设置70

71
//打开上次下载的文件或新建文件72
long lStartPos =0;73
System.IO.FileStream fs;74
if (System.IO.File.Exists(StrFileName))75
{76
fs= System.IO.File.OpenWrite(StrFileName);77
lStartPos=fs.Length;78
fs.Seek(lStartPos,System.IO.SeekOrigin.Current); //移动文件流中的当前指针79
}80
else81
{82
fs = new System.IO.FileStream(StrFileName,System.IO.FileMode.Create);83
lStartPos =0;84
}85

86
//打开网络连接87
try88
{89
System.Net.HttpWebRequest request =(System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(StrUrl);90
if ( lStartPos>0)91
request.AddRange((int)lStartPos); //设置Range值92

93
//向服务器请求,获得服务器回应数据流94
System.IO.Stream ns= request.GetResponse().GetResponseStream();95

96
byte[] nbytes = new byte[512];97
int nReadSize=0;98
nReadSize=ns.Read(nbytes,0,512);99
while( nReadSize >0)100
{101
fs.Write(nbytes,0,nReadSize);102
nReadSize=ns.Read(nbytes,0,512);103
}104
fs.Close();105
ns.Close();106
Console.WriteLine("下载完成");107
}108
catch(Exception ex)109
{110
fs.Close();111
Console.WriteLine("下载过程中出现错误:"+ex.ToString());112
}113
} 114

Accept: 

浙公网安备 33010602011771号