【问题标题】:Partial file uploads being automatically deleted部分文件上传被自动删除
【发布时间】:2012-03-16 20:21:56
【问题描述】:

我有一些 c# 代码正在通过 HttpWebRequests 将一些文件上传到我的 apache 服务器。在上传过程中,我可以使用ls -la 查看不断增长的文件大小。

现在,如果我拉我的计算机网络电缆,部分文件上传仍保留在服务器上。

但是,如果我只是关闭我的 c# 应用程序,部分文件将被删除!

我认为这是由于我的流被优雅地关闭造成的。我怎样才能防止这种行为?无论上传应用的行为如何,我都希望保留我的部分文件上传。

我尝试使用析构函数来abort 我的请求流,以及调用System.Environment.Exit(1),但都没有任何效果。

【问题讨论】:

  • 这取决于服务器端代码。
  • 没有服务器端代码,只是一个 HTTP Put
  • 换句话说,服务器端代码在Apache本身。
  • 你能指定吗?我找不到任何似乎可以控制如何处理部分上传文件的设置,并且由于我可以强制执行我想要的行为,因此必须有一个解决方案。
  • 我不知道;我对 Apache 一无所知。

标签: c# apache http


【解决方案1】:

拉网线永远不会等同于中止流或关闭套接字,因为它在较低的OSI level中是失败的。

只要应用程序关闭,网络会话就会中止,任何挂起的操作都会取消。我认为没有任何解决方法,除非您以编程方式将文件传输拆分为 更小的块并在进行过程中保存它们(这样您将进行手动增量传输,但它需要一些服务器端代码)。

【讨论】:

  • 我有一个 iOS 应用程序,它能够中止正在进行的上传。该文件保留在服务器上。只有我的 c# 应用程序的行为是这样的。我注意到在我的析构函数完成之后文件才被删除。
  • 我刚才也尝试了 IT Hit 演示(付费 webdav 库),但上传失败并不会删除文件!显然我在某处遗漏了一个关键部分。
【解决方案2】:

编写一个非常简单的 HTTP 代理,它不断接受连接但从不关闭与服务器的连接

甚至更简单,使用netcat 1.10(虽然这只会接受一个连接)

nc -q $FOREVER -l -p 12345 -c 'nc $YOUR_SERVER 80'

然后将你的 C# 客户端连接到 localhost:12345

【讨论】:

    【解决方案3】:

    这可能是一个愚蠢的建议,但如果您在应用程序关闭时调用Process.GetCurrentProcess().Kill(); 会怎样?

    【讨论】:

    • 无效。直到我退出我的应用程序的析构函数,或者在本例中是 Kill 命令之后,该文件才会从服务器中删除。
    【解决方案4】:

    在查看部分上传的处理之前,首先测试whether turning keepalives on in Apache configuration 解决了您接收部分上传的问题。

    这可能会减少断开连接的次数,从而减少处理部分数据的需要。这种断开连接可能是由于客户端、服务器造成的,但通常是由于防火墙等中间节点造成的。 keepalives 选项的作用是保持稳定的“虚拟”流量(0 字节长的数据负载),从而向各方通告连接仍然有效。

    对于并发负载繁重的大型站点,keepalive 是一件坏事,这就是为什么它们默认关闭的原因。该选项使 Apache 的连接管理更加复杂,阻止了优化的连接重用,并且还有一点额外的网络流量。但也许您有一个不需要担心的特殊用例。

    如果您的客户端往往过早崩溃(也就是说,如果您始终看到上传的稳定进度),Keepalives 将永远不会帮助您。如果问题与网络相关,它们可能会对您有很大帮助。

    如果您的客户逐渐生成数据,上传数据块之间存在较长的延迟,它们将为您提供极大的帮助。

    【讨论】:

    • 感谢您的意见。我有一个 iPhone 应用程序以及 IT Hit 试用版 (webdavsystem.com/client),其性能完全符合我的需要。也就是说,可以强制关闭 iphone 应用程序(在模拟器中运行),或强制关闭 IT Hit 的 c# 应用程序(通过 ctrl-alt-del 或简单的 X),并且正在上传的部分文件保留在服务器上。这表明我需要的是可能的。我自己的自定义 c# 应用程序的行为方式并非如此。当服务器关闭时,任何部分上传都会立即从服务器中删除。我相信 Apache 不是问题。
    【解决方案5】:

    您是否检查过,如果您的应用程序进入

    void FinishUpload(IAsyncResult result) {…}
    

    (line 240) 中止/终止应用程序时?如果是这样,您可以考虑不输入回调。这有点脏,但可能会给你一个开始挖掘的位置。

    【讨论】:

    • 它没有进入那个函数。
    • 好的。然后我会像@AnthonyBlake 一样指向 SendChunked 方向。
    【解决方案6】:

    Apache 是否支持 HTTPRequest 的 SendChunked 属性?

    如果是这样,值得一试。

    http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.sendchunked.aspx

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 2011-12-26
      • 2018-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多