现在的位置: 首页 > 综合 > 正文

用C#实现HTTP协议下的多线程文件传输

2017年05月31日 ⁄ 综合 ⁄ 共 13138字 ⁄ 字号 评论关闭
很多人都有过使用网络蚂蚁或网络快车软件下载互联网文件的经历,这些软件的使用可以大大加速互联网上文件的传输速度,减少文件传输的时间。这些软件为什么
有如此大的魔力呢?其主要原因是这些软件都采用了多线程下载和断点续传技术。如果我们自己来编写一个类似这样的程序,也能够快速的在互联网上下载文件,那
一定是非常愉快的事情。下面我就讲一讲如何利用C#语言编写一个支持多线程下载文件的程序,你会看到利用C#语言编写网络应程序是多么的容易,从中也能体
会到C#语言中强大的网络功能。ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
 
 首先介绍一下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通讯。ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
 
 HttpWebRequest类实现了很多通过HTTP访问WEB服务器上文件的高级功能。HttpWebRequest类对WebRequest中定
义的属性和方法提供支持,HttpWebRequest将发送到Internet资源的公共HTTP标头的值公开为属性,由方法或系统设置,常用的由属性
或方法设置的HTTP标头为:接受, 由Accept属性设置, 连接, 由Connection属性和KeepAlive属性设置,
Content-Length, 由ContentLength属性设置, Content-Type, 由ContentType属性设置, 范围,
由AddRange方法设置. 实际使用中是将标头信息正确设置后,传递到WEB服务器,WEB服务器根据要求作出回应。ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
 
 HttpWebResponse类继承自WebResponse类,专门处理从WEB服务器返回的HTTP响应,这个类实现了很多方法,具有很多属性,
可以全面处理接收到的互联网信息。在HttpWebResponse类中,对于大多数通用的HTTP标头字段,都有独立的属性与其对应,程序员可以通过这
些属性方便的访问位于HTTP接收报文标头字段中的信息,本例中用到的HttpWebResponse类属性为:ContentLength
既接收内容的长度。ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  有了以上的了解后,下面看看这两个类的用法,要创建HttpWebRequest对象,不要直接使用HttpWebRequest的构造函数,而要使用WebRequest.Create方法初始化一个HttpWebRequest实例,如: ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
HttpWebRequest hwr=(HttpWebRequest)WebRequest.Create(http://www.163.com/); ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
创建了这个对象后,就可以通过HttpWebRequest属性,设置很多HTTP标头字段的内容,如hwr.AddRange(100,1000);设置接收对象的范围为100-1000字节。ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
HttpWebReques
对象使用GetResponse()方法时,会返回一个HttpWebResponse对象,为提出HTTP返回报文信息,需要使用
HttpWebResponse的GetResponseStream()方法,该方法返回一个Stream对象,可以读取HTTP返回的报文,如:首先
定义一个Strean 对象 public System.IO.Stream ns; 然后 ns=hwr.GetResponse
().GetResponseStream
();即可创建Stream对象。有了以上的准备知识后下面开始设计我们的多线程互联网文件的下载程序,首先打开Visual Studio.Net
集成开发环境,选择“文件”、“新建”、“项目”,然后选择“Visual
C#项目”,在向导右边列表框中选中“Windows应用程序”,输入项目名称,如本例为:httpftp,然后选择“确定”按钮,向导自动生成了一个
Windows应用程序项目。首先打开窗口设计器设计应用程序窗口,增加如下控件:ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  一个列表框 listBox1 三个文本标签 label1-label3 三个文本框 textBox1-textBox3 一个开始接收按钮 button1 设计好的窗口如下图:ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’

ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’

控件定义代码是: ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’

public System.Windows.Forms.ListBox listBox1;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
private System.Windows.Forms.Label label1;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
private System.Windows.Forms.TextBox textBox1ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
private System.Windows.Forms.Button button1;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
private System.Windows.Forms.Label label2;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
private System.Windows.Forms.TextBox textBox2;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
private System.Windows.Forms.Label label3;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
private System.Windows.Forms.TextBox textBox3;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
private System.Windows.Forms.Label label4;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
private System.Windows.Forms.TextBox textBox4;

ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
打开Form1的代码编辑器,增加如下的命名空间:ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’

using System.Net;//网络功能ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
using System.IO;//流支持ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
using System.Threading ;//线程支持

ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
增加如下的程序变量:ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’

public bool[] threadw; //每个线程结束标志ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
public string[] filenamew;//每个线程接收文件的文件名ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
public int[] filestartw;//每个线程接收文件的起始位置ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
public int[] filesizew;//每个线程接收文件的大小ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
public string strurl;//接受文件的URLŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
public bool hb;//文件合并标志ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
public int thread;//进程数

ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
定义一个HttpFile类,用于管理接收线程,其代码如下:ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’

public class HttpFileŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
{ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  public Form1 formm;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  public int threadh;//线程代号ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  public string filename;//文件名ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  public string strUrl;//接收文件的URLŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  public FileStream fs;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  public HttpWebRequest request;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  public System.IO.Stream ns;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  public byte[] nbytes;//接收缓冲区ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  public int nreadsize;//接收字节数ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  public HttpFile(Form1 form,int thread)//构造方法ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  {ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  formm=form;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  threadh=thread;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  }ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  ~HttpFile()//析构方法ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  {ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  formm.Dispose ();ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  }ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  public void receive()//接收线程ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  {ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  filename=formm.filenamew[threadh];ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  strUrl=formm.strurl;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  ns=null;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  nbytes= new byte[512];ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  nreadsize=0;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  formm.listBox1 .Items .Add ("线程"+threadh.ToString ()+"开始接收");ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  fs=new FileStream (filename,System.IO.FileMode.Create);ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  tryŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  {ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  request=(HttpWebRequest)HttpWebRequest.Create (strUrl);ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  //接收的起始位置及接收的长度ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  request.AddRange(formm.filestartw [threadh],ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  formm.filestartw [threadh]+formm.filesizew [threadh]);ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  ns=request.GetResponse ().GetResponseStream ();//获得接收流ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  nreadsize=ns.Read (nbytes,0,512);ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  while (nreadsize>0)ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  {ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  fs.Write (nbytes,0,nreadsize);ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  nreadsize=ns.Read (nbytes,0,512);ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  formm.listBox1 .Items .Add ("线程"+threadh.ToString ()+"正在接收");ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  }ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  fs.Close();ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  ns.Close ();ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  }ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  catch (Exception er)ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  {ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  MessageBox.Show (er.Message );ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  fs.Close();ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  }ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  formm.listBox1 .Items.Add ("进程"+threadh.ToString ()+"接收完毕!");ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  formm.threadw[threadh]=true;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  }ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
}

ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
该类和Form1类处于统一命名空间,但不包含在Form1类中。下面定义“开始接收”按钮控件的事件响应函数:ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’

private void button1_Click(object sender, System.EventArgs e)ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
{ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  DateTime dt=DateTime.Now;//开始接收时间ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  textBox1.Text =dt.ToString ();ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  strurl=textBox2.Text .Trim ().ToString ();ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  HttpWebRequest request;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  long filesize=0;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  tryŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  {ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  request=(HttpWebRequest)HttpWebRequest.Create (strurl);ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  filesize=request.GetResponse ().ContentLength;//取得目标文件的长度ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  request.Abort ();ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  }ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  catch (Exception er)ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  {ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  MessageBox.Show (er.Message );ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  }ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  // 接收线程数ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  thread=Convert.ToInt32 (textBox4.Text .Trim().ToString (),10);ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  //根据线程数初始化数组ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  threadw=new bool [thread];ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  filenamew=new string [thread];ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  filestartw=new int [thread];ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  filesizew=new int[thread];ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  //计算每个线程应该接收文件的大小ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  int filethread=(int)filesize/thread;//平均分配ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  int filethreade=filethread+(int)filesize%thread;//剩余部分由最后一个线程完成ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  //为数组赋值ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  for (int i=0;iŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  {ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  threadw[i]=false;//每个线程状态的初始值为假ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  filenamew[i]=i.ToString ()+".dat";//每个线程接收文件的临时文件名ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  if (iŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  {ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  filestartw[i]=filethread*i;//每个线程接收文件的起始点ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  filesizew[i]=filethread-1;//每个线程接收文件的长度ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  }ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  elseŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  {ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  filestartw[i]=filethread*i;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  filesizew[i]=filethreade-1;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  }ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  }ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  //定义线程数组,启动接收线程ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  Thread[] threadk=new Thread [thread];ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  HttpFile[] httpfile=new HttpFile [thread];ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  for (int j=0;jŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  {ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  httpfile[j]=new HttpFile(this,j);ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  threadk[j]=new Thread(new ThreadStart (httpfile[j].receive ));ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  threadk[j].Start ();ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  }ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  //启动合并各线程接收的文件线程ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  Thread hbth=new Thread (new ThreadStart (hbfile));ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  hbth.Start ();ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
}

ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
合并文件的线程hbfile定义在Form1类中,定义如下:ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’

public void hbfile()ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
{ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  while (true)//等待ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  {ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  hb=true;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  for (int i=0;iŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  {ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  if (threadw[i]==false)//有未结束线程,等待ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  {ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  hb=false;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  Thread.Sleep (100);ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  break;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  }ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  }ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  if (hb==true)//所有线程均已结束,停止等待,ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  {ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  break;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  }ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  }ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  FileStream fs;//开始合并ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  FileStream fstemp;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  int readfile;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  byte[] bytes=new byte[512];ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  fs=new FileStream (textBox3.Text .Trim ().ToString (),System.IO.FileMode.Create);ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  for (int k=0;kŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  {ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  fstemp=new FileStream (filenamew[k],System.IO.FileMode .Open);ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  while (true)ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  {ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  readfile=fstemp.Read (bytes,0,512);ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  if (readfile>0)ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  {ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  fs.Write (bytes,0,readfile);ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  }ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  elseŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  {ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  break;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  }ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  }ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  fstemp.Close ();ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  }ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  fs.Close ();ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  DateTime dt=DateTime.Now;ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  textBox1.Text =dt.ToString ();//结束时间ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
  MessageBox.Show ("接收完毕!!!");ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
}

ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’
ŠÊ!‚ßU× :www.netcsharp.cn4 ß1Üö’

此,一个多线程下载文件的程序就大功告成了,注意在输入本地文件名时,应按如下格式输入:“c://test//httpftp//bin//
d.htm”,因”/”后的字符在C#中是转义字符,线程数并非越大越好,一般5个线程就可以了,该程序在Visual Studio.Net
2002开发环境及Windows xp
操作系统上通过。

抱歉!评论已关闭.