在Win中通过HTTP协议向服务器端上传.doc_第1页
在Win中通过HTTP协议向服务器端上传.doc_第2页
在Win中通过HTTP协议向服务器端上传.doc_第3页
在Win中通过HTTP协议向服务器端上传.doc_第4页
在Win中通过HTTP协议向服务器端上传.doc_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

在WinForm中通过HTTP协议向服务器端上传文件 相信用ASP.NET写一个上传文件的网页大家都会写但是有没有人想过通过在WinForm中通过HTTP协议上传文件呢 有些人说要向服务器端上传文件用FTP协议不是很简单吗效率又高为什么还要使用HTTP协议那么麻烦呢这里面有几个原因 1FTP服务器的部署相对麻烦还要设置权限权限设置不对还会惹来一系列的安全问题。 2如果双方都还有防火墙又不想开发FTP相关的一些端口时HTTP就会大派用场就像WEB Services能穿透防火墙一样。 3其他的.还在想呢. 但是使用HTTP也有他的一些问题例如不能断点续传大文件上传很难速度很慢所以HTTP协议上传的文件大小不应该太大。 说了这么多原归正传一般来说在Winform里通过HTTP上传文件有几种可选的方法 1前面提到的Web Services就是一种很好的方法通过编写一个WebMethod包含有 byte 类型的参数然后调用Web Services的方法文件内容就会以Base64编码传到服务器上然后重新保存即可。 WebMethod public void UploadFilebyte contentstring filename. Stream sw new StreamWriter. sw.Close 当然这种通过Base64编码的方法效率比较低那么可以采用WSE支持附件并以2进制形式传送效率会更高。 2除了通过WebService另外一种更简单的方法就是通过WebClient或者HttpWebRequest来模拟HTTP的POST动作来实现。这时候首先需要编写一个 web form来响应上传代码如下 ltDOCTYPE HTML PUBLIC quot-/W3C/DTD HTML 4.0 Transitional/ENquot gt lthtmlgt ltheadgt lttitlegtWebForm1lt/titlegt ltmeta namequotGENERATORquot ContentquotMicrosoft Visual Studio .NET 7.1quotgt ltmeta namequotCODE_LANGUAGEquot ContentquotCquotgt ltmeta namequotvs_defaultClientScriptquot contentquotJavaScriptquotgt ltmeta namequotvs_targetSchemaquot contentquot/intellisense/ie5quotgt lt/headgt ltbodygt ltform idquotForm1quot methodquotpostquot runatquotserverquotgt lt/formgt lt/bodygt lt/htmlgt using System using System.Collections using System.ComponentModel using System.Data using System.Drawing using System.Web using System.Web.SessionState using System.Web.UI using System.Web.UI.WebControls using System.Web.UI.HtmlControls namespace UploadFileWeb . / ltsummarygt / WebForm1 的摘要说明。 / lt/summarygt public class WebForm1 : System.Web.UI.Page . private void Page_Loadobject sender System.EventArgs e . / 在此处放置用户代码以初始化页面 foreach string f in Request.Files.AllKeys . HttpPostedFile file Request.Filesf file.SaveAsquotD:Tempquot file.FileName if Request.ParamsquottestKeyquot null . Response.WriteRequest.ParamsquottestKeyquot Web 窗体设计器生成的代码region Web 窗体设计器生成的代码 override protected void OnInitEventArgs e . / / CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。 / InitializeComponent base.OnInite / ltsummarygt / 设计器支持所需的方法 - 不要使用代码编辑器修改 / 此方法的内容。 / lt/summarygt private void InitializeComponent . this.Load new System.EventHandlerthis.Page_Load endregion 其实这个页面跟我们平常写的上传文件代码是一样的在Web 页的Request对象中包含有Files这个对象里面就包含了通过POST方式上传的所有文件的信息这时所需要做的就是调用 Request.Filesi.SaveAs方法。 但是怎么让才能在WinForm里面模拟想Web Form POST 数据呢System.Net命名空间里面提供了两个非常有用的类一个是WebClient另外一个是HttpWebRequest类。如果我们不需要通过代理服务器来上传文件那么非常简单只需要简单的调用WebClient.UploadFile方法就能实现上传文件 private void button1_Clickobject sender System.EventArgs e . WebClient myWebClient new WebClient myWebClient.UploadFilequothttp:/localhost/UploadFileWeb/WebForm1.aspx2222POST2222D:/Temp/Java/JavaStart/JavaStart2.exequot 是不是觉得很简单呢确实就这么简单。 但是如果要通过代理服务器上传又怎么办呢那就需要使用到HttpWebRequest但是该类没有Upload方法但是幸运的是我们通过Reflector反编译了WebClient.UploadFile方法后我们发现其内部也是通过WebRequest来实现的代码如下 public byte UploadFilestring address string method string fileName . string text1 string text2 WebRequest request1 string text3 byte buffer1 byte buffer2 long num1 byte buffer3 int num2 WebResponse response1 byte buffer4 DateTime time1 long num3 string textArray1 FileStream stream1 null try . fileName Path.GetFullPathfileName time1 DateTime.Now num3 time1.Ticks text1 quot-quot num3.ToStringquotxquot if this.m_headers null . this.m_headers new WebHeaderCollection text2 this.m_headersquotContent-Typequot if text2 null . if text2.ToLowerCultureInfo.InvariantCulture.StartsWithquotmultipart/quot . throw new WebExceptionSR.GetStringquotnet_webclient_Multipartquot else . text2 quotapplication/octet-streamquot this.m_headersquotContent-Typequot quotmultipart/form-data boundaryquot text1 this.m_responseHeaders null stream1 new FileStreamfileName FileMode.Open FileAccess.Read request1 WebRequest.Createthis.GetUriaddress request1.Credentials this.Credentials this.CopyHeadersTorequest1 request1.Method method textArray1 new string7 textArray10 quot-quot textArray11 text1 textArray12 quotrnContent-Disposition: form-data namequotfilequot filenamequotquot textArray13 Path.GetFileNamefileName textArray14 quotquotrnContent-Type: quot textArray15 text2 textArray16 quotrnrnquot text3 string.ConcattextArray1 buffer1 Encoding.UTF8.GetBytestext3 buffer2 Encoding.ASCII.GetBytesquotrn-quot text1 quotrnquot num1 9223372036854775807 try . num1 stream1.Length request1.ContentLength num1 long buffer1.Length long buffer2.Length catch . buffer3 new byteMath.Minint 8192 int num1 using Stream stream2 request1.GetRequestStream . stream2.Writebuffer1 0 buffer1.Length do . num2 stream1.Readbuffer3 0 buffer3.Length if num2 0 . stream2.Writebuffer3 0 num2 while num2 0 stream2.Writebuffer2 0 buffer2.Length stream1.Close stream1 null response1 request1.GetResponse this.m_responseHeaders response1.Headers return this.ResponseAsBytesresponse1 catch Exception exception1 . if stream1 null . stream1.Close stream1 null if exception1 is WebException exception1 is SecurityException . throw throw new WebExceptionSR.GetStringquotnet_webclientquot exception1 return buffer4 在这段代码里面其实最关键的就是如何模拟POST请求通过分析代码和监视HTTP我们可以发现模拟的POST格式如下 -8c64f47716481f0 /时间戳 Content-Disposition: form-data namequotfilequot filenamequota.txtquot /文件名 Content-Type: application/octet-stream /文件的内容 -8c64f47716481f0 这时候我们只需自己编码来模拟这么一组数据就行我们还可以好好借鉴MS的代码呢以下就是代码声明一下我是借用了别人的代码 public class wwHttp . / ltsummarygt / Fires progress events when using GetUrlEvents to retrieve a URL. / lt/summarygt public event OnReceiveDataHandler OnReceiveData / ltsummarygt / Determines how data is POSTed when cPostBuffer is set. / 1 - UrlEncoded / 2 - Multi-Part form vars / 4 - XML raw buffer content type: text/xml / lt/summarygt public int PostMode . get . return this.nPostMode set . this.nPostMode value / ltsummarygt / User name used for Authentication. / To use the currently logged in user when accessing an NTLM resource you can use quotAUTOLOGINquot. / lt/summarygt public string Username . get . return this.cUsername set . cUsername value / ltsummarygt / Password for Authentication. / lt/summarygt public string Password . get .return this.cPassword set .this.cPassword value / ltsummarygt / Address of the Proxy Server to be used. / Use optional DEFAULTPROXY value to specify that you want to IEs Proxy Settings / lt/summarygt public string ProxyAddress . get .return this.cProxyAddress set .this.cProxyAddress value / ltsummarygt / Semicolon separated Address list of the servers the proxy is not used for. / lt/summarygt public string ProxyBypass . get .return this.cProxyBypass set .this.cProxyBypass value / ltsummarygt / Username for a password validating Proxy. Only used if the proxy info is set. / lt/summarygt public string ProxyUsername . get .return this.cProxyUsername set .this.cProxyUsername value / ltsummarygt / Password for a password validating Proxy. Only used if the proxy info is set. / lt/summarygt public string ProxyPassword . get .return this.cProxyPassword set .this.cProxyPassword value / ltsummarygt / Timeout for the Web request in seconds. Times out on connection read and send operations. / Default is 30 seconds. / lt/summarygt public int Timeout . get .return this.nConnectTimeout set .this.nConnectTimeout value / ltsummarygt / Error Message if the Error Flag is set or an error value is returned from a method. / lt/summarygt public string ErrorMsg . get . return this.cErrorMsg set . this.cErrorMsg value / ltsummarygt / Error flag if an error occurred. / lt/summarygt public bool Error . get . return this.bError set . this.bError value / ltsummarygt / Determines whether errors cause exceptions to be thrown. By default errors / are handled in the class and the Error property is set for error conditions. / not implemented at this time. / lt/summarygt public bool ThrowExceptions . get . return bThrowExceptions set . this.bThrowExceptions value / ltsummarygt / If set to a non-zero value will automatically track cookies. The number assigned is the cookie count. / lt/summarygt public bool HandleCookies . get . return this.bHandleCookies set . this.bHandleCookies value public CookieCollection Cookies . get . return this.oCookies set . this.Cookies value public HttpWebResponse WebResponse . get . return this.oWebResponse set . this.oWebResponse value public HttpWebRequest WebRequest . get . return this.oWebRequest set . this.oWebRequest value / member properties /string cPostBuffer quotquot MemoryStream oPostStream BinaryWriter oPostData int nPostMode 1 int nConnectTimeout 30 string cUserAgent quotWest Wind HTTP .NETquot string cUsername quotquot string cPassword quotquot string cProxyAddress quotquot string cProxyBypass quotquot string cProxyUsername quotquot string cProxyPassword quotquot bool bThrowExceptions false bool bHandleCookies false string cErrorMsg quotquot bool bError false HttpWebResponse oWebResponse HttpWebRequest oWebRequest CookieCollection oCookies string cMultiPartBoundary quot-7cf2a327f01aequot public void wwHTTP . / / TODO: Add constructor logic here / / ltsummarygt / Adds POST form variables to the request buffer. / HttpPostMode determines how parms are handled. / 1 - UrlEncoded Form Variables. Uses key and value pairs ie. quotNamequotquotRickquot to create URLEncoded content / 2 - Multi-Part Forms - not supported / 4 - XML block - Post a single XML block. Pass in as Key 1st Parm / other - raw content buffer. Just assign to Key. / lt/summarygt / ltparam namequotKeyquotgtKey value or raw buffer depending on post typelt/paramgt / ltparam namequotValuequotgtValue to store. Used only in key/value pair modeslt/paramgt public void AddPostKeystring Key byte Value . if this.oPostData null . this.oPostStream new MemoryStream this.oPostData new BinaryWriterthis.oPostStream if Key quotRESETquot . this.oPostStream new MemoryStream this.oPostData new BinaryWriterthis.oPostStream switchthis.nPostMode . case 1: this.oPostData.WriteEncoding.GetEncoding1252.GetBytes Key quotquot System.Web.HttpUtility.UrlEncodeValue quotampquot break case 2: this.oPostData.Write Encoding.GetEncoding1252.GetBytes quot-quot this.cMultiPartBoundary quotrnquot quotContent-Disposition: form-data namequotquot Keyquotquotrnrnquot this.oPostData.Write Value this.oPostData.Write Encoding.GetEncoding1252.GetBytesquotrnquot break default: this.oPostData.Write Value break public void AddPostKeystring Key string Value . this.AddPostKeyKeyEncoding.GetEncoding1252.GetBytesValue / ltsummarygt / Adds a fully self contained POST buffer to the request. / Works for XML or previously encoded content. / lt/summarygt / ltparam namequotPostBufferquotgtlt/paramgt public void AddPostKeystring FullPostBuffer . this.oPostData.Write Encoding.GetEncoding1252.GetBytesFullPostBuffer public bool AddPostFilestring Keystring FileName . byte lcFile if this.nPostMode 2 . this.cErrorMsg quotFile upload allowed only with Multi-part formsquot this.bError true return false try . FileStream loFile new FileStreamFileNameSystem.IO.FileMode.OpenSystem.IO.FileAccess.Read lcFile new byteloFile.Length loFile.Readl

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论