以往,我们肯定知道,在搞Web应用的时候,我们都可能会遇到提供文件下载的功能需求,比如我以前做的一个客户许可证管理系统,客户购买ERP系统后,通常我们会根据客户的机器的机器码生成一个许可文件,而这个许可文件是有时间限制的,一年后会过期,过期之后客户需要重新获取许可,以表示继续使用我们的超级牛B产品,如果客户不再获取许可,就表明客户不再使用我们的超级牛B产品。

后来一想,是啊,倒不如咱们弄个Web程序,让客户自行登入,输入机器码后,自动生成许可文件,然后客户在页面上点击下载就行了。提供下载功能其实很常见,像许多软件下载站等。

不过,我们是否考虑过,如果我们编写一个仅仅提供HTTP下载相关的少数功能的应用程序,我们似乎没有必要大动干戈在机器上弄个服务器搞个Web站点。通常这种情况,做个小小的窗口程序就可以完事了。所以,就会想到使用桌面应用程序来提供HTTP下载这想法了。

其实,这个实现起来并不复杂,System.Net命名空间下提供了一个HttpListener类,它可监听客户端传入的HTTP请求,然后返回一个HttpListenerContext对象,再通过HttpListenerContext对象可以得到用于处理请求/响应有关的对象。

根据这个思路,我们也可以轻松做到提供下载功能,原来和Web方式是一样的,就是在响应请求时插入Content-Disposition标头,值为attachment;filename=<文件名>的方法就能实现。

  1. private async void btnListen_Click(object sender, EventArgs e)
  2. {
  3. HttpListener listener = new HttpListener();
  4. listener.Prefixes.Add("http://+:80/download/");
  5. listener.Start();
  6. btnListen.Enabled = false;
  7. HttpListenerContext context = await listener.GetContextAsync();
  8. if (context != null)
  9. {
  10. // 添加Content-Disposition标头
  11. context.Response.AppendHeader("Content-Disposition", "attachment;filename=" + WebUtility.UrlEncode( Path.GetFileName(lblFilePath.Text)));
  12. try
  13. {
  14. using (FileStream stream = File.OpenRead(lblFilePath.Text))
  15. {
  16. // 添加内容说明符
  17. context.Response.ContentType = MediaTypeNames.Application.Octet;
  18. // 内容长度
  19. context.Response.ContentLength64 = stream.Length;
  20. // 回发数据给客户端
  21. byte[] buffer = new byte[1024];
  22. int n = stream.Read(buffer, 0, buffer.Length);
  23. while (n > 0)
  24. {
  25. context.Response.OutputStream.Write(buffer, 0, n);
  26. n = stream.Read(buffer, 0, buffer.Length);
  27. }
  28. context.Response.Close(); //关闭
  29. }
  30. }
  31. catch(Exception ex)
  32. {
  33. MessageBox.Show(ex.Message);
  34. }
  35. }
  36. listener.Stop(); //停止监听
  37. btnListen.Enabled = true;
  38. }

在设置filename时将文件名加上WebUtility.UrlEncode进行编码是防止当文件名中包含中文时呈现乱码。

而发送文件给客户端就简单多了,和普通的流操作没有区别,把从文件中读到的数据写入Response.OutputStream流中即可,发送完毕后,调用Close方法关闭HttpListenerResponse对象,因此处理已经完成,没有必再开着它占用资源。

监听地址为http://+:80/download/,表示HttpListener将监在80端口上的所有主机名接收到的请求,后面的路径中加上 download/ 只是为了不与IIS的默认localhost地址冲突,因为我开启了IIS。

运行后,选择一个文件,然后点击按钮开始监听。

随后在浏览器中输入 http://localhost/download/ ,按回车,就可以测试下载了。

桌面应用也可以提供HTTP文件下载的更多相关文章

  1. Windows Server 2012 没有远程桌面授权服务器可以提供许可证,远程会话被中断

    今天在登录公司内部的服务器的时候,无法进行远程访问. 弹出错误信息:没有远程桌面授权服务器可以提供许可证,远程会话被中断 经过网上的寻找,原来是server 2012 远程登录只提供120天的使用期限 ...

  2. 解决mstsc无法连接问题:由于没有远程桌面授权服务器可以提供许可证

    一.故障案例① 今天上午在给测试组的IIS新增https的时候,发现远程弹出如下错误: 由于没有远程桌面授权服务器可以提供许可证,远程会话被中断.请跟服务器管理员联系. 度了度,原来也是很常见的一种错 ...

  3. Server2008R2:由于没有远程桌面授权服务器可以提供许可证,.....错误的解决 ---设计师零张

    一直使用远程桌面连接一台windows2008server服务器,今天突然报错,连不上了:   “由于没有远程桌面授权服务器可以提供许可证,远程会话被中断.请跟服务器管理员联系.”       由于是 ...

  4. ”由于没有远程桌面授权服务器可以提供许可证,远程会话被中断“的解决方案

    由于windows server 2012 R2 Datacenter 安装了 远程桌面角色,但是这个角色是120天免费的,需要购买授权的. 解决方案: 删除这个角色,就可以正常进行远程桌面连接了.但 ...

  5. 处理问题:windows server 2016由于没有远程桌面授权服务器可以提供许可证,远程会话被中断。请跟服务器管理员联系

    windows server可以多用户同时登陆,默认最大远程登录数量为2,如果有更多人需要同时远程登录,则需要安装远程桌面授权服务,第一次安装后,免费期为120天,超过则无法正常远程登录. 解决办法如 ...

  6. windows Sever 2012 远程提示:由于没有远程桌面授权服务器可以提供许可证,远程会话被中断。请跟服务器管理员联系。

    远程windows Sever 2012 时候 远程提示:由于没有远程桌面授权服务器可以提供许可证,远程会话被中断.请跟服务器管理员联系. 原因: windows server可以多用户同时登陆,默认 ...

  7. 远程桌面授权server没有提供许可证问题解决方法

    今天远程server报如图所看到的错误,网上查找的方法 方法一:(亲測有效) mstsc /V:192.168.0.3 /admin  方法二:(因为server正在使用中,未作測试) 删除远程桌面服 ...

  8. Windows远程报错:由于没有远程桌面授权服务器可以提供许可证,远程会话被中断

    故障原因:Windowsserver超过两人的远程连接是收费的,有120天免费试用期,超过这个时间再连接就会报错. 解决方法一: 进行续费 解决方法二: 1,在运行里运行 mstsc /v:ip    ...

  9. 配置IIS服务器提供APP文件下载

    [IIS7.IIS7.5] 1)打开IIS服务管理器,左边点到计算机(也可设置特定网站) 2)右边功能项中找到MIME类型,双击打开3)右键“添加”4)扩展名中填写".apk",M ...

随机推荐

  1. ubuntu编译airplay

    1.alsa/asoundlib.h: No such file or directory 缺少一个库: apt-get install libasound2-dev   2.fatal error: ...

  2. 《ASP.NET》数据绑定—DataList

    DataList控件是.NET中的一个控件.DataList控件以表的形式呈现数据(在属性生成器中能够编辑),通过该控件,您能够使用不同的布局来显示数据记录(使用模板编辑).比如,将数据记录排成列或行 ...

  3. 不能实现RadioButton默认选择

    当用RadioButton时,希望在程序运行的时候默认一个选项: CheckRadioButton(IDC_RADIO1,IDC_RADIO2,IDC_RADIO1); //CheckRadioBut ...

  4. 自己定义msi安装包的运行过程

    有时候我们须要在程序中运行还有一个程序的安装.这就须要我们去自己定义msi安装包的运行过程. 比方我要做一个安装管理程序,能够依据用户的选择安装不同的子产品.当用户选择了三个产品时,假设分别显示这三个 ...

  5. 细数AutoLayout以来UIView和UIViewController新增的相关API

    本文转载至 http://www.itjhwd.com/autolayout-uiview-uiviewcontroller-api/ 细数AutoLayout以来UIView和UIViewContr ...

  6. 2016/06/09 ThinkPHP3.2.3使用分页

    效果图:

  7. Mac版idea使用总结

    1.设置文档注释快捷键:快捷键设置里搜索 Fix doc comment 2.IDEA不显示项目project视图(转载于 https://blog.csdn.net/oyimiyangguang12 ...

  8. CSS3 弹性盒子(Flex Box) 微信小程序图片通栏

    {{define "chkUrl"}} <!DOCTYPE html><html lang="zh-cmn-Hans"><head ...

  9. android支付

    这里不讲具体的某个平台的支付使用,在工作中,公司使用到了ping++支付,使用它的好处是可以不用关心某个平台的支付了,例如:微信支付.支付宝支付等,太多的平台有个整合,是一个很好的事情,当然这也减轻了 ...

  10. 百度自然语言处理api用法

    def words url = "https://aip.baidubce.com/rpc/2.0/nlp/v1/lexer?access_token=1111111" param ...