首页 > 解决方案 > System.Net.WebResponse 抛出“System.Net.WebException:操作已超时”但已连接到 Web 服务器

问题描述

我有一个方法,旨在将文件从 HTTP URL 下载到字节数组:

private static byte[] DownloadFileToByteArrayWorker(HttpWebRequest Request, int bufferLength)
{
    byte[] responseByes = null;

    //Round up to the nearest multiple of 1024
    bufferLength = AdjustBufferLength(bufferLength);

    Request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
    Request.ServicePoint.Expect100Continue = false;
    Request.Headers.Add(HttpRequestHeader.CacheControl, "no-cache");

    using (var Response = (HttpWebResponse)Request.GetResponse())
    {
        using (Stream ResponseStream = Response.GetResponseStream())
        {
            using (MemoryStream ms = new MemoryStream())
            {
                int count = 0;
                byte[] buf = new byte[bufferLength];
                while ((count = ResponseStream.Read(buf, 0, buf.Length)) > 0)
                {
                    ms.Write(buf, 0, count);
                }
                responseByes = ms.ToArray();
            }
        }
    }

    return responseByes;
}

无论我设置 HttpWebRequest 的 Timeout 属性多长时间,Request.GetResponse()都会引发超时异常。我可以通过我的日志验证程序在出错之前正在等待完整的超时时间,但是,将我的日志与 Web 服务器日志相关联表明 Web 服务器几乎立即发回了响应。

一个有趣的提示是,当我通过负载均衡器而不是直接访问同一个 Web 服务器时,它实际上会立即下载文件。此外,如果我直接在 Web 浏览器中通过 Web 服务器访问 URL(不需要代理,顺便说一句),我也可以通过这种方式立即从各个 Web 服务器下载文件。

一些额外的细节:

有什么建议么?

标签: c#webrequestwebresponse

解决方案


正如您所说,您的代码仅在您调用负载均衡器时才有问题,我认为问题在于您的客户端发送100 continue请求但您的负载均衡器不知道如何处理它。

这就是您的客户端在连接开始后没有立即发送所有数据的原因。

您可以在HTTP rfc第 8.2.3 节中找到有关 100 continue 的更多信息。

要在 c# 中修复客户端的行为,您必须添加以下代码:

ServicePointManager.Expect100Continue = false;

您可以在此处查看有关此功能的完整文档。


推荐阅读