日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C#实现HTTP协议:多线程文件传输

發布時間:2024/9/5 C# 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#实现HTTP协议:多线程文件传输 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

很多人都有過使用網絡螞蟻或網絡快車互聯網文件的經歷,這些軟件的使用可以大大加速互聯網上文件的傳輸速度,減少文件傳輸的時間。這些軟件為什么有如此大的魔力呢?其主要原因是這些軟件都采用了多線程下載和斷點續傳技術。如果我們自己來編寫一個類似這樣的程序,也能夠快速的在互聯網上下載文件,那一定是非常愉快的事情。下面我就講一講如何利用C#語言編寫一個支持多線程下載文件的程序,你會看到利用C#語言編寫網絡應用程序是多么的容易,從中也能體會到C#語言中強大的網絡功能。

首先介紹一下HTTP協議, HTTP亦即Hpyer Text Transfer Protocal的縮寫,它是現代互聯網上最重要的一種網絡協議,超文本傳輸協議位于TCP/IP協議的應用層,是一個面向無連接、簡單、快速的C/S結構的協議。HTTP的工作過程大體上分連接、請求、響應和斷開連接四個步驟。C#語言對HTTP協議提供了良好的支持,在類庫中提供了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對象。有了以上的準備知識后下面開始設計我們的多線程互聯網文件的下載程序,首先打開.Net集成開發環境,選擇“文件”、“新建”、“項目”,然后選擇“Visual C#項目”,在向導右邊列表框中選中“Windows應用程序”,輸入項目名稱,如本例為:httpftp,然后選擇“確定”按鈕,向導自動生成了一個 Windows應用程序項目。首先打開窗口設計器設計應用程序窗口,增加如下控件:

    一個列表框 listBox1 三個文本標簽 label1-label3 三個文本框 textBox1-textBox3 一個開始接收按鈕 button1 設計好的窗口如下圖:

    ?

    控件定義代碼是:

  • public?System.Windows.Forms.ListBox?listBox1; ?
  • private?System.Windows.Forms.Label?label1; ?
  • private?System.Windows.Forms.TextBox?textBox1 ?
  • private?System.Windows.Forms.Button?button1; ?
  • private?System.Windows.Forms.Label?label2; ?
  • private?System.Windows.Forms.TextBox?textBox2; ?
  • private?System.Windows.Forms.Label?label3; ?
  • private?System.Windows.Forms.TextBox?textBox3; ?
  • private?System.Windows.Forms.Label?label4; ?
  • private?System.Windows.Forms.TextBox?textBox4;??
  • 打開Form1的代碼編輯器,增加如下的命名空間:

  • using?System.Net;//網絡功能? ?
  • using?System.IO;//流支持 ?
  • using?System.Threading?;//線程支持??
  • 增加如下的程序變量:

  • public?bool[]?threadw;?//每個線程結束標志 ?
  • public?string[]?filenamew;//每個線程接收文件的文件名 ?
  • public?int[]?filestartw;//每個線程接收文件的起始位置 ?
  • public?int[]?filesizew;//每個線程接收文件的大小 ?
  • public?string?strurl;//接受文件的URL ?
  • public?bool?hb;//文件合并標志 ?
  • public?int?thread;//進程數??
  • 定義一個HttpFile類,用于管理接收線程,其代碼如下:

  • public?class?HttpFile ?
  • { ?
  •  public?Form1?formm; ?
  •  public?int?threadh;//線程代號 ?
  •  public?string?filename;//文件名 ?
  •  public?string?strUrl;//接收文件的URL ?
  •  public?FileStream?fs; ?
  •  public?HttpWebRequest?request; ?
  •  public?System.IO.Stream?ns; ?
  •  public?byte[]?nbytes;//接收緩沖區 ?
  •  public?int?nreadsize;//接收字節數 ?
  •  public?HttpFile(Form1?form,int?thread)//構造方法 ?
  •  { ?
  • formm=form; ?
  • threadh=thread; ?
  •  } ?
  •  ~HttpFile()//析構方法 ?
  •  { ?
  • formm.Dispose?(); ?
  •  } ?
  •  public?void?receive()//接收線程 ?
  •  { ?
  • filename=formm.filenamew[threadh]; ?
  • strUrl=formm.strurl; ?
  • ns=null; ?
  • nbytes=?new?byte[512]; ?
  • nreadsize=0; ?
  • formm.listBox1?.Items?.Add?("線程"+threadh.ToString?()+"開始接收"); ?
  • fs=new?FileStream?(filename,System.IO.FileMode.Create); ?
  • try?
  • { ?
  •  request=(HttpWebRequest)HttpWebRequest.Create?(strUrl); ?
  •  //接收的起始位置及接收的長度? ?
  •  request.AddRange(formm.filestartw?[threadh], ?
  •  formm.filestartw?[threadh]+formm.filesizew?[threadh]); ?
  •  ns=request.GetResponse?().GetResponseStream?();//獲得接收流 ?
  •  nreadsize=ns.Read?(nbytes,0,512); ?
  •  while?(nreadsize>0) ?
  •  { ?
  • fs.Write?(nbytes,0,nreadsize); ?
  • nreadsize=ns.Read?(nbytes,0,512); ?
  • formm.listBox1?.Items?.Add?("線程"+threadh.ToString?()+"正在接收"); ?
  •  } ?
  •  fs.Close(); ?
  •  ns.Close?(); ?
  • } ?
  • catch?(Exception?er) ?
  • { ?
  •  MessageBox.Show?(er.Message?); ?
  •  fs.Close(); ?
  • } ?
  • formm.listBox1?.Items.Add?("進程"+threadh.ToString?()+"接收完畢!"); ?
  • formm.threadw[threadh]=true; ?
  •  } ?
  • }??
  • 該類和Form1類處于統一命名空間,但不包含在Form1類中。下面定義“開始接收”按鈕控件的事件響應函數:

  • private?void?button1_Click(object?sender,?System.EventArgs?e) ?
  • { ?
  •  DateTime?dt=DateTime.Now;//開始接收時間 ?
  •  textBox1.Text?=dt.ToString?(); ?
  •  strurl=textBox2.Text?.Trim?().ToString?(); ?
  •  HttpWebRequest?request; ?
  •  long?filesize=0; ?
  •  try?
  •  { ?
  • request=(HttpWebRequest)HttpWebRequest.Create?(strurl); ?
  • filesize=request.GetResponse?().ContentLength;//取得目標文件的長度 ?
  • request.Abort?(); ?
  •  } ?
  •  catch?(Exception?er) ?
  •  { ?
  • MessageBox.Show?(er.Message?); ?
  •  } ?
  •  //?接收線程數 ?
  •  thread=Convert.ToInt32?(textBox4.Text?.Trim().ToString?(),10); ?
  •  //根據線程數初始化數組 ?
  •  threadw=new?bool?[thread]; ?
  •  filenamew=new?string?[thread]; ?
  •  filestartw=new?int?[thread]; ?
  •  filesizew=new?int[thread]; ?
  • ?
  •  //計算每個線程應該接收文件的大小 ?
  •  int?filethread=(int)filesize/thread;//平均分配 ?
  •  int?filethreade=filethread+(int)filesize%thread;//剩余部分由最后一個線程完成 ?
  •  //為數組賦值 ?
  •  for?(int?i=0;i<?thread;i++) ?
  •  { ?
  • threadw[i]=false;//每個線程狀態的初始值為假 ?
  • filenamew[i]=i.ToString?()+".dat";//每個線程接收文件的臨時文件名 ?
  • if?(i<?thread-1) ?
  • { ?
  •  filestartw[i]=filethread*i;//每個線程接收文件的起始點 ?
  •  filesizew[i]=filethread-1;//每個線程接收文件的長度 ?
  • } ?
  • else?
  • { ?
  •  filestartw[i]=filethread*i; ?
  •  filesizew[i]=filethreade-1; ?
  • } ?
  •  } ?
  •  //定義線程數組,啟動接收線程 ?
  •  Thread[]?threadk=new?Thread?[thread]; ?
  •  HttpFile[]?httpfile=new?HttpFile?[thread]; ?
  •  for?(int?j=0;j<?thread;j++) ?
  •  { ?
  • httpfile[j]=new?HttpFile(this,j); ?
  • threadk[j]=new?Thread(new?ThreadStart?(httpfile[j].receive?)); ?
  • threadk[j].Start?(); ?
  •  } ?
  •  //啟動合并各線程接收的文件線程 ?
  •  Thread?hbth=new?Thread?(new?ThreadStart?(hbfile)); ?
  •  hbth.Start?(); ?
  • }??
  • 合并文件的線程hbfile定義在Form1類中,定義如下:

  • public?void?hbfile() ?
  • { ?
  •  while?(true)//等待 ?
  •  { ?
  • hb=true; ?
  • for?(int?i=0;i<?thread;i++) ?
  • { ?
  •  if?(threadw[i]==false)//有未結束線程,等待 ?
  •  { ?
  • hb=false; ?
  • Thread.Sleep?(100); ?
  • break; ?
  •  } ?
  • } ?
  • if?(hb==true)//所有線程均已結束,停止等待, ?
  • { ?
  •  break; ?
  • } ?
  •  } ?
  •  FileStream?fs;//開始合并 ?
  •  FileStream?fstemp; ?
  •  int?readfile; ?
  •  byte[]?bytes=new?byte[512]; ?
  •  fs=new?FileStream?(textBox3.Text?.Trim?().ToString?(),System.IO.FileMode.Create); ?
  •  for?(int?k=0;k<?thread;k++) ?
  •  { ?
  • fstemp=new?FileStream?(filenamew[k],System.IO.FileMode?.Open); ?
  • while?(true) ?
  • { ?
  •  readfile=fstemp.Read?(bytes,0,512); ?
  •  if?(readfile>0) ?
  •  { ?
  • fs.Write?(bytes,0,readfile); ?
  •  } ?
  •  else?
  •  { ?
  • break; ?
  •  } ?
  • } ?
  • fstemp.Close?(); ?
  •  } ?
  •  fs.Close?(); ?
  •  DateTime?dt=DateTime.Now; ?
  •  textBox1.Text?=dt.ToString?();//結束時間 ?
  •  MessageBox.Show?("接收完畢!!!"); ?
  • }??
  • 至此,一個多線程下載文件的程序就大功告成了,注意在輸入本地文件名時,應按如下格式輸入:“c:\\test\\httpftp\\bin\\d.htm”,因”\”后的字符在C#中是轉義字符,線程數并非越大越好,一般5個線程就可以了,該程序在Visual Studio.Net 2002開發環境及Windows xp 上通過。

    =========================================================

    本文為轉載,轉載必須確保本文完整并完整保留原作者信息和本文鏈接

    E-mail: khler@163.com

    QQ:?????23381103

    MSN:???pragmac@hotmail.com

    原文:http://developer.51cto.com/art/200908/147018.htm

    申明:轉載只為傳播知識,讓更多人享受作者智慧的結晶!

    如原作者對轉載于此有異議,請立即聯系本人,本人將在

    第一時間刪除,并深表歉意!

    =========================================================

    ?


    轉載于:https://www.cnblogs.com/khler/archive/2009/10/16/1584313.html

    與50位技術專家面對面20年技術見證,附贈技術全景圖

    總結

    以上是生活随笔為你收集整理的C#实现HTTP协议:多线程文件传输的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。