c# - 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 服务器下载文件。
一些额外的细节:
- 我在 Windows 2012 R2 上使用 .NET Framework 4.7。
- 我尝试连接的 Web 服务器是 RHEL7 上的 Apache。我不确定具体的 Apache 版本
- 我正在为 HTTP 流量保留的特定端口上连接到 Web 服务器(单独的网站托管在 HTTPS 的不同端口号上)
- 没有网络代理
有什么建议么?
解决方案
正如您所说,您的代码仅在您调用负载均衡器时才有问题,我认为问题在于您的客户端发送100 continue
请求但您的负载均衡器不知道如何处理它。
这就是您的客户端在连接开始后没有立即发送所有数据的原因。
您可以在HTTP rfc第 8.2.3 节中找到有关 100 continue 的更多信息。
要在 c# 中修复客户端的行为,您必须添加以下代码:
ServicePointManager.Expect100Continue = false;
您可以在此处查看有关此功能的完整文档。
推荐阅读
- python - 你如何解决这个循环,以便“阅读更多”按钮只在每张卡片中折叠?
- google-cloud-platform - Google Cloud Dataflow - 是否可以定义从 BigQuery 读取数据并写入本地数据库的管道?
- gpu - 有没有办法在多 GPU 上运行 Rapids 时间序列模块(ARIMA、ESM)?
- java - 如果无法连接到 Xserver,则使命令在没有 gui 的情况下运行
- amazon-web-services - 允许 ECS 任务访问 RDS
- java - MPChart 在适合屏幕上不显示轴标签
- api - 如何在flutter中将odoo api与odoo数据库集成
- django - 在 Wagtail 中发布新博客文章时向订阅者发送电子邮件通知
- java - 在执行下面的代码时我看不到结果但是在调试时我可以执行下面的代码
- game-maker-studio-2 - 当你与骷髅碰撞时将运行的游戏制作者死亡代码不能像它应该的那样工作