代码之家  ›  专栏  ›  技术社区  ›  SillyMonkey

使用httpwebrequest上载Put文件时出错

  •  3
  • SillyMonkey  · 技术社区  · 16 年前

    我们有一个.NET 2.0 WinForms应用程序,需要通过WebDAV将文件上载到iis6服务器。我们不时收到来自远程办公室的投诉,他们收到以下错误消息之一

    • 基础连接已关闭: 发送时发生意外错误。
    • 基础连接已关闭: 在上发生意外错误 接收。

    这种情况似乎只出现在大文件中(~20MB以上)。我用家用电脑中的40MB文件测试过它,并尝试将“睡眠”放在循环中以模拟慢速连接,因此我怀疑这是由于网络问题导致的。但是

    1. 远程办公室的IT没有帮助
    2. 我想排除我的代码有问题的可能性。

    所以-任何人都能发现任何错误,或者建议任何可能“防弹”代码来解决这个问题的解决方法吗?谢谢你的帮助。代码的缩减版本如下:

        public bool UploadFile(string localFile, string uploadUrl)
        {
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uploadUrl);
    
            try
            {
                req.Method = "PUT";
                req.AllowWriteStreamBuffering = true;
                req.UseDefaultCredentials = Program.WebService.UseDefaultCredentials;
                req.Credentials = Program.WebService.Credentials;
                req.SendChunked = false;
                req.KeepAlive = true;
                Stream reqStream = req.GetRequestStream();
                FileStream rdr = new FileStream(localFile, FileMode.Open, FileAccess.Read);
                byte[] inData = new byte[4096];
                int bytesRead = rdr.Read(inData, 0, inData.Length);
    
                while (bytesRead > 0)
                {
                    reqStream.Write(inData, 0, bytesRead);
                    bytesRead = rdr.Read(inData, 0, inData.Length);
                }
    
                reqStream.Close();
                rdr.Close();
    
                System.Net.HttpWebResponse response = (HttpWebResponse)req.GetResponse();
                if (response.StatusCode != HttpStatusCode.OK && response.StatusCode!=HttpStatusCode.Created)
                {
                    MessageBox.Show("Couldn't upload file");
                    return false;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                return false;
            }
            return true;
        }
    
    6 回复  |  直到 16 年前
        1
  •  6
  •   kgiannakakis    16 年前

    尝试设置 KeepAlive 虚假:

    req.KeepAlive = false;
    

    这将允许关闭并再次打开连接。它不允许使用 persistent connection . 我在网上找到了很多建议这样做的参考资料,以解决类似于你的错误。这是一个相关的 link .

    无论如何,使用http-put(或http-post)上传大文件不是一个好主意。最好使用ftp或下载/上传管理器。这些将自动为您处理重试、连接问题和超时。上传速度也会更快,你也可以恢复一个停止的上传。如果您决定继续使用HTTP,那么至少应该尝试添加一个重试机制。如果上传时间太长,那么很有可能由于代理、服务器超时、防火墙或其他原因而失败。

        2
  •  5
  •   Marc Gravell    16 年前

    要消除代码中出现错误的风险,请尝试使用 WebClient :

    using (WebClient client = new WebClient())
    {
        client.UseDefaultCredentials = Program.WebService.UseDefaultCredentials;
        client.Credentials = Program.WebService.Credentials;
        client.UploadFile(uploadUrl, "PUT", localFile);
    }
    
        3
  •  1
  •   Community CDub    8 年前

    也许可以尝试使用post,但真正的罪魁祸首可能是内容类型。

    尝试设置

    req.ContentType = "application/octet-stream";
    req.ContentLength = inData.Length;
    

    或者在这里查看接受答案中的代码: Upload files with HTTPWebrequest (multipart/form-data)

    我的示例和我提供的链接都涉及修改ContentType——我的示例更简单,但可能不起作用,因为大多数接收文件的应用程序都希望使用多部分

        4
  •  1
  •   sesame    16 年前

    请检查在IIS管理器的[网站]选项卡上是否设置了[启用http保留alives]。

        5
  •  0
  •   david valentine    16 年前

    上载的大小可能受到限制。

    请参阅此处进行一次讨论: http://www.codeproject.com/KB/aspnet/uploadlargefilesaspnet.aspx

        6
  •  0
  •   Precipitous    16 年前

    首先检查一些基本配置。以下任一项的默认值可能会导致文件上载出现问题-包括连接终止。我相信IIS6永远不会允许文件上传>2GB(即使它可以完成,无论配置如何)。 Msdn describes these nicely .

    <httpRuntime executionTimeout = "30"  maxRequestLength="200"/>
    

    编辑:当然,这是ASP.NET配置,它假定您正在运行自己的WebDAV服务器或 3rd party server 在ASP.NET中。如果它是一个不同的WebDAV服务器,您将需要寻找等价的服务器。