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 ("接收完毕!!!");  

 

你可能感兴趣的:(http协议,传输,多线程文件)