【问题标题】:Problem with C# HTTP PUT request codeC# HTTP PUT 请求代码的问题
【发布时间】:2011-11-02 05:36:57
【问题描述】:

我正在尝试通过 Amazon S3 已经为我生成的 PUT 请求 URL 将文件发送到 S3。

我的代码适用于小文件,但在发送几分钟后它会在大文件 (>100 mb) 上出错。

有错误:请求被中止:请求被取消。在 System.Net.ConnectStream.InternalWrite(布尔异步,字节 [] 缓冲区,Int32 偏移量,Int32 大小,AsyncCallback 回调,对象状态) 在 System.Net.ConnectStream.Write(Byte[] 缓冲区,Int32 偏移量,Int32 大小)

谁能告诉我我的代码有什么问题阻止它发送大文件?这不是由于 Amazon PUT 请求 URL 过期,因为我将其设置为 30 分钟,并且仅在发送几分钟后就会出现问题。

代码最终异常出在这行代码上:dataStream.Write(byteArray, 0, byteArray.Length);

再一次,它适用于我发送到 S3 的较小文件。只是不是大文件。

WebRequest request = WebRequest.Create(PUT_URL_FINAL[0]);
//PUT_URL_FINAL IS THE PRE-SIGNED AMAZON S3 URL THAT I AM SENDING THE FILE TO

request.Timeout = 360000; //6 minutes

request.Method = "PUT";

//result3 is the filename that I am sending                                     
request.ContentType =
    MimeType(GlobalClass.AppDir + Path.DirectorySeparatorChar + "unzip" +
             Path.DirectorySeparatorChar +
             System.Web.HttpUtility.UrlEncode(result3));

byte[] byteArray =
    File.ReadAllBytes(
        GlobalClass.AppDir + Path.DirectorySeparatorChar + "unzip" +
        Path.DirectorySeparatorChar +
        System.Web.HttpUtility.UrlEncode(result3));

request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream();

// this is the line of code that it eventually quits on.  
// Works fine for small files, not for large ones
dataStream.Write(byteArray, 0, byteArray.Length); 

dataStream.Close();

//This will return "OK" if successful.
WebResponse response = request.GetResponse();
Console.WriteLine("++ HttpWebResponse: " +
                  ((HttpWebResponse)response).StatusDescription);

【问题讨论】:

  • 这可能很明显,但您确定 Amazon 的 S3 服务允许超过 100MB 的 HTTP 请求吗?
  • 我不认为这是问题所在。完整的 100mb 永远不会被发送(它会在一两分钟后停止)。我可以使用任何第 3 方 S3 软件程序发送文件,他们通过 PUT 请求发送它,它工作正常。除了 S3 的问题之外,我认为我的代码有问题。
  • 在上面的代码中,你的超时时间只有 6 分钟,而不是 30 分钟。
  • 我在创建 S3 PUT URL 时使用的超时时间是 30 分钟。 URL 链接将在 30 分钟后过期。我的代码中的超时是连接超时,设置为 6 分钟。超时不是问题,因为大文件传输甚至从未达到 6 分钟标记。
  • 如果你分块写入数据流怎么办?传输一定数量的字节后总是失败吗?

标签: c# http web


【解决方案1】:

您应该将WebRequestTimeout 属性设置为更高的值。它会导致请求在完成之前超时。

【讨论】:

  • 非常感谢。这就是问题所在。我认为这是一个连接超时,而不是实际超时,超过时会停止传输。
【解决方案2】:

使用FiddlerWireshark 比较线路上的内容(第三方工具)和不工作时(您的代码)...一旦您知道了差异,您就可以更改您的相应地编码...

【讨论】:

    【解决方案3】:

    我会尝试分块编写它并拆分字节数组。它可能会被一大块窒息。

    类似这样的:

            const int chunkSize = 500;
            for (int i = 0; i < byteArray.Length; i += chunkSize)
            {
                int count = i + chunkSize > byteArray.Length ? byteArray.Length - i : chunkSize;
                dataStream.Write(byteArray, i, count);
            }
    

    可能想仔细检查以确保它写了所有内容,我只对其进行了非常基本的测试。

    【讨论】:

    • @fraX 完成。将块大小更改为您认为合适的大小,例如 8KB 之类的,500 字节只是一个示例。
    【解决方案4】:

    只是一个粗略的猜测,但你不应该有:

    request.ContentLength = byteArray.LongLength;
    

    代替:

    request.ContentLength = byteArray.Length;
    

    再想一想,100 MB = 100 * 1024 * 1024

    【讨论】:

    • 那没有任何效果。无论如何,谢谢。
    猜你喜欢
    • 2023-03-12
    • 2012-07-10
    • 2019-09-27
    • 2020-06-22
    • 2013-11-17
    • 2021-10-24
    • 2014-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多