使用HttpWebRequest上传带有PUT的文件时出错

Sil*_*key 3 c# networking

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

  • 基础连接已关闭:发送时发生意外错误.
  • 底层连接已关闭:接收时发生意外错误.

这似乎只发生在大文件(约20Mb加).我用家用电脑上的40Mb文件对它进行了测试,并尝试将'Sleep'放在循环中以模拟慢速连接,所以我怀疑它归结为网络问题......但是

  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;
    }
Run Code Online (Sandbox Code Playgroud)

kgi*_*kis 6

尝试将KeepAlive设置为false:

req.KeepAlive = false;
Run Code Online (Sandbox Code Playgroud)

这将允许关闭连接并再次打开.它不允许使用持久连接.我发现网上有很多引用,以便解决类似于你的错误.这是一个相关的链接.

无论如何,使用HTTP PUT(或HTTP POST)上传大文件并不是一个好主意.最好使用FTP或下载/上传管理器.这些将自动处理重试,连接问题,超时.上传速度也会更快,您也可以恢复停止上传.如果您决定继续使用HTTP,则至少应尝试添加重试机制.如果上传时间过长,则很可能由于代理,服务器超时,防火墙或者您的代码没有理由而导致上传失败.


Mar*_*ell 6

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

using (WebClient client = new WebClient())
{
    client.UseDefaultCredentials = Program.WebService.UseDefaultCredentials;
    client.Credentials = Program.WebService.Credentials;
    client.UploadFile(uploadUrl, "PUT", localFile);
}
Run Code Online (Sandbox Code Playgroud)