http协议-多线程文件传输

简介:

 HTTP亦即Hpyer Text Transfer Protocal的缩写,它是现代互联网上最重要的一种网络协议,超文本传输协议位于TCP/IP协议的应用层,是一个面向无连接、简单、快速的C/S结构的协议。HTTP的工作过程大体上分连接、请求、响应和断开连接四个步骤。C#语言对HTTP协议提供了良好的支持,在.NET类库中提供了WebRequest和WebResponse类,这两个类都包含在System.Net命名空间中,利用这两个类可以实现很多高级的网络功能,本文中多线程文件下载就是利用这两个类实现的。 WebRequest和WebResponse都是抽象基类,因此在程序中不能直接作为对象使用,必须被继承,实际使用中,可根据URI参数中的URI前缀选用它们合适的子类,对于HTTP这类URI,HttpWebRequest和HttpWebResponse类可以用于处理客户程序同WEB服务器之间的HTTP通讯。

HttpWebRequest类实现了很多通过HTTP访问WEB服务器上文件的高级功能。HttpWebRequest类对WebRequest中定义的属性和方法提供支持,HttpWebRequest将发送到Internet资源的公共HTTP标头的值公开为属性,由方法或系统设置,常用的由属性或方法设置的HTTP标头为:接受, 由Accept属性设置, 连接, 由Connection属性和KeepAlive属性设置, Content-Length, 由ContentLength属性设置, Content-Type, 由ContentType属性设置, 范围, 由AddRange方法设置. 实际使用中是将标头信息正确设置后,传递到WEB服务器,WEB服务器根据要求作出回应。

HttpWebResponse类继承自WebResponse类,专门处理从WEB服务器返回的HTTP响应,这个类实现了很多方法,具有很多属性,可以全面处理接收到的互联网信息。在HttpWebResponse类中,对于大多数通用的HTTP标头字段,都有独立的属性与其对应,程序员可以通过这些属性方便的访问位于HTTP接收报文标头字段中的信息,本例中用到的HttpWebResponse类属性为:ContentLength 既接收内容的长度。

 

要创建HttpWebRequest对象,不要直接使用HttpWebRequest的构造函数,而要使用WebRequest.Create方法初始化一个HttpWebRequest实例,如:

HttpWebRequest hwr=(HttpWebRequest)WebRequest.Create(http://www.163.com/); 
创建了这个对象后,就可以通过HttpWebRequest属性,设置很多HTTP标头字段的内容,如hwr.AddRange(100,1000);设置接收对象的范围为100-1000字节。

HttpWebReques对象使用GetResponse()方法时,会返回一个HttpWebResponse对象,为提出HTTP返回报文信息,需要使用HttpWebResponse的GetResponseStream()方法,该方法返回一个Stream对象,可以读取HTTP返回的报文,
如:
首先定义一个Strean 对象
public System.IO.Stream ns;
然后
ns=hwr.GetResponse ().GetResponseStream ();即可创建Stream对象。
 
  1. 代码  
  2.  
  3. using System.Net;//网络功能  
  4. using System.IO;//流支持  
  5. using System.Threading ;//线程支持  
  6.     
  7.  
  8. 增加如下的程序变量:  
  9.  
  10. public bool[] threadw; //每个线程结束标志  
  11. public string[] filenamew;//每个线程接收文件的文件名  
  12. public int[] filestartw;//每个线程接收文件的起始位置  
  13. public int[] filesizew;//每个线程接收文件的大小  
  14. public string strurl;//接受文件的URL  
  15. public bool hb;//文件合并标志  
  16. public int thread;//进程数  
  17.  
  18. 定义一个HttpFile类,用于管理接收线程,其代码如下:  
  19.  
  20.   public class HttpFile  
  21. {  
  22.  public Form1 formm;  
  23.  public int threadh;//线程代号  
  24.  public string filename;//文件名  
  25.  public string strUrl;//接收文件的URL  
  26.  public FileStream fs;  
  27.  public HttpWebRequest request;  
  28.  public System.IO.Stream ns;  
  29.  public byte[] nbytes;//接收缓冲区  
  30.  public int nreadsize;//接收字节数  
  31.  public HttpFile(Form1 form,int thread)//构造方法  
  32.  {  
  33.   formformm=form;  
  34.   threadthreadh=thread;  
  35.  }  
  36.  HttpFile()//析构方法  
  37.  {  
  38.   formm.Dispose ();  
  39.  }  
  40.  public void receive()//接收线程  
  41.  {  
  42.   filename=formm.filenamew[threadh];  
  43.   strUrl=formm.strurl;  
  44.   ns=null;  
  45.   nbytesnew byte[512];  
  46.   nreadsize=0;  
  47.   formm.listBox1 .Items .Add ("线程"+threadh.ToString ()+"开始接收");  
  48.   fs=new FileStream (filename,System.IO.FileMode.Create);  
  49.   try  
  50.   {  
  51.    request=(HttpWebRequest)HttpWebRequest.Create (strUrl);  
  52.    //接收的起始位置及接收的长度  
  53.    request.AddRange(formm.filestartw [threadh],  
  54.    formm.filestartw [threadh]+formm.filesizew [threadh]);  
  55.    ns=request.GetResponse ().GetResponseStream ();//获得接收流  
  56.    nreadsize=ns.Read (nbytes,0,512);  
  57.    while (nreadsize>0)  
  58.    {  
  59.     fs.Write (nbytes,0,nreadsize);  
  60.     nreadsize=ns.Read (nbytes,0,512);  
  61.     formm.listBox1 .Items .Add ("线程"+threadh.ToString ()+"正在接收");  
  62.    }  
  63.    fs.Close();  
  64.    ns.Close ();  
  65.   }  
  66.   catch (Exception er)  
  67.   {  
  68.    MessageBox.Show (er.Message );  
  69.    fs.Close();  
  70.   }  
  71.   formm.listBox1 .Items.Add ("进程"+threadh.ToString ()+"接收完毕!");  
  72.   formm.threadw[threadh]=true;  
  73.  }  
  74. }  
  75.  
  76. 该类和Form1类处于统一命名空间,但不包含在Form1类中。下面定义“开始接收”按钮控件的事件响应函数:  
  77.  
  78.   private void button1_Click(object sender, System.EventArgs e)  
  79. {  
  80.  DateTime dt=DateTime.Now;//开始接收时间  
  81.  textBox1.Text =dt.ToString ();  
  82.  strurl=textBox2.Text .Trim ().ToString ();  
  83.  HttpWebRequest request;  
  84.  long filesize=0;  
  85.  try  
  86.  {  
  87.   request=(HttpWebRequest)HttpWebRequest.Create (strurl);  
  88.   filesize=request.GetResponse ().ContentLength;//取得目标文件的长度  
  89.   request.Abort ();  
  90.  }  
  91.  catch (Exception er)  
  92.  {  
  93.   MessageBox.Show (er.Message );  
  94.  }  
  95.  // 接收线程数  
  96.  thread=Convert.ToInt32 (textBox4.Text .Trim().ToString (),10);  
  97.  //根据线程数初始化数组  
  98.  threadw=new bool [thread];  
  99.  filenamew=new string [thread];  
  100.  filestartw=new int [thread];  
  101.  filesizew=new int[thread];  
  102.  //计算每个线程应该接收文件的大小  
  103.  int filethread=(int)filesize/thread;//平均分配  
  104.  int filethreadfilethreade=filethread+(int)filesize%thread;//剩余部分由最后一个线程完成  
  105.  //为数组赋值  
  106.  for (int i=0;i<thread;i++)  
  107.  {  
  108.   threadw[i]=false;//每个线程状态的初始值为假  
  109.   filenamew[i]=i.ToString ()+".dat";//每个线程接收文件的临时文件名  
  110.   if (i<thread-1)  
  111.   {  
  112.    filestartw[i]=filethread*i;//每个线程接收文件的起始点  
  113.    filesizew[i]=filethread-1;//每个线程接收文件的长度  
  114.   }  
  115.   else  
  116.   {  
  117.    filestartw[i]=filethread*i;  
  118.    filesizew[i]=filethreade-1;  
  119.   }  
  120.  }  
  121.  //定义线程数组,启动接收线程  
  122.  Thread[] threadk=new Thread [thread];  
  123.  HttpFile[] httpfile=new HttpFile [thread];  
  124.  for (int j=0;j<thread;j++)  
  125.  {  
  126.   httpfile[j]=new HttpFile(this,j);  
  127.   threadk[j]=new Thread(new ThreadStart (httpfile[j].receive ));  
  128.   threadk[j].Start ();  
  129.  }  
  130.  //启动合并各线程接收的文件线程  
  131.  Thread hbth=new Thread (new ThreadStart (hbfile));  
  132.  hbth.Start ();  
  133. }  
  134.  
  135. 合并文件的线程hbfile定义在Form1类中,定义如下:  
  136.  
  137.   public void hbfile()  
  138. {  
  139.  while (true)//等待  
  140.  {  
  141.   hb=true;  
  142.   for (int i=0;i<thread;i++)  
  143.   {  
  144.    if (threadw[i]==false)//有未结束线程,等待  
  145.    {  
  146.     hb=false;  
  147.     Thread.Sleep (100);  
  148.     break;  
  149.    }  
  150.   }  
  151.   if (hb==true)//所有线程均已结束,停止等待,  
  152.   {  
  153.    break;  
  154.   }  
  155.  }  
  156.  FileStream fs;//开始合并  
  157.  FileStream fstemp;  
  158.  int readfile;  
  159.  byte[] bytes=new byte[512];  
  160.  fs=new FileStream (textBox3.Text .Trim ().ToString (),System.IO.FileMode.Create);  
  161.  for (int k=0;k<thread;k++)  
  162.  {  
  163.   fstemp=new FileStream (filenamew[k],System.IO.FileMode .Open);  
  164.   while (true)  
  165.   {  
  166.    readfile=fstemp.Read (bytes,0,512);  
  167.    if (readfile>0)  
  168.    {  
  169.     fs.Write (bytes,0,readfile);  
  170.    }  
  171.    else  
  172.    {  
  173.     break;  
  174.    }  
  175.   }  
  176.   fstemp.Close ();  
  177.  }  
  178.  fs.Close ();  
  179.  DateTime dt=DateTime.Now;  
  180.  textBox1.Text =dt.ToString ();//结束时间  
  181.  MessageBox.Show ("接收完毕!!!");  

 


本文转自linzheng 51CTO博客,原文链接:http://blog.51cto.com/linzheng/1079266

相关文章
|
2月前
|
缓存 监控 搜索推荐
301重定向实现原理全面解析:从HTTP协议到SEO最佳实践
301重定向是HTTP协议中的永久重定向状态码,用于告知客户端请求的资源已永久移至新URL。它在SEO中具有重要作用,能传递页面权重、更新索引并提升用户体验。本文详解其工作原理、服务器配置方法(如Apache、Nginx)、对搜索引擎的影响及最佳实践,帮助实现网站平稳迁移与优化。
421 68
|
27天前
HTTP协议中请求方式GET 与 POST 什么区别 ?
GET和POST的主要区别在于参数传递方式、安全性和应用场景。GET通过URL传递参数,长度受限且安全性较低,适合获取数据;而POST通过请求体传递参数,安全性更高,适合提交数据。
300 2
|
2月前
|
存储 网络协议 安全
HTTP 协议及会话跟踪机制详解
本文详解了 HTTP 协议的核心知识,包括其定义(超文本传输协议,基于 TCP,规定客户端与服务器通信规则)及与 HTTPS 的区别(安全性、端口、资源消耗)。 介绍了 GET 与 POST 请求的差异(参数限制、安全性、应用场景),以及 Restful 风格(通过 URL 定位资源,请求方式决定操作)。列举了常见 HTTP 状态码(如 200 成功、404 资源未找到),对比了转发与重定向的区别(服务器端一次请求 vs 客户端两次请求)。 还阐述了会话跟踪机制:Cookie 基于客户端存储,通过Set-Cookie和Cookie头实现,安全性较低;Session 基于服务端存储,依赖 C
227 1
|
1月前
|
缓存 网络协议 UED
深度解析HTTP协议从版本0.9至3.0的演进和特性。
总的来说,HTTP的演进是互联网技术不断发展和需求日益增长的结果。每一次重要更新都旨在优化性能,增进用户体验,适应新的应用场景,而且保证了向后兼容,让互联网的基础架构得以稳定发展。随着网络技术继续进步,我们可以预期HTTP协议在未来还会继续演化。
334 0
|
2月前
|
XML 安全 网络架构
深度对比SOAP与HTTP协议:详细理解它们的工作原理和差异
在设计服务和系统交云策略时,考虑到上述差异是至关重要的。SOAP适合需要高安全性、可靠性和事务支持的企业级应用。而HTTP适合Web界面浏览、RESTful服务和需要快速响应的轻量级通信。根据具体需求和上下文,开发者可以选择合适的协议以实现最优的系统性能和用户体验。
280 0
|
3月前
|
缓存
HTTP协议深度剖析:常见请求头信息讲解
这就是HTTP请求头背后的工作原理,希望通过比作“邮差”和“标签”,可以让你对这个繁琐技术更有感触,更得心应手。尽管这些信息可能很琐碎,但了解了它们的含义和工作方式,就等于揭开了HTTP协议神秘的面纱,掌控了网络交流的核心。你还等什么,赶快动手尝试一下吧!
123 17
|
2月前
HTTP协议中常见的状态码 ?
HTTP协议状态码分为1xx、2xx、3xx、4xx、5xx五类。常见状态码包括:101(切换协议)、200(请求成功)、302(重定向)、401(未认证)、404(资源未找到)、500(服务器错误)。
267 0
|
3月前
|
存储 缓存 前端开发
http协议调试代理工具,Fiddler免费版下载,抓包工具使用教程
Fiddler是一款功能强大的HTTP协议调试代理工具,能记录并检查电脑与互联网间的HTTP通信,支持断点设置和数据编辑。相比其他网络调试器,Fiddler操作更简单且用户友好,支持查看Cookie、HTML、JS、CSS等文件内容。它还具备HTTPS抓包、过滤设置、统计页面总重量等功能,适用于安全测试与功能测试。通过插件扩展,用户可自定义视图或分析缓存行为。支持多种HTTP请求方法(如GET、POST等)及状态码分类(1xx-5xx),是开发者调试网络请求的得力工具。同类工具有HttpWatch、Firebug、Wireshark等。
351 1
|
3月前
|
网络协议 算法 调度
深入探讨HTTP/2.0协议的细节
在理解了所有这些细节后,你现在应该更加清楚HTTP/2.0是如何让数据高效地在互联网上快速移动的。而这只是一个简化的类比,实际的技术细节和协议规范更加丰富和复杂。随着时间的推移,HTTP/2.0的实现将继续优化,为我们提供更可靠、高效的网络体验。
76 0