上传速度问题:HttpWebRequest [重复]
Posted
技术标签:
【中文标题】上传速度问题:HttpWebRequest [重复]【英文标题】:Upload Speed Issue : HttpWebRequest [duplicate] 【发布时间】:2012-12-12 18:22:54 【问题描述】:我正在使用 HttpWebRequest 将文件上传到某个服务器,现在的问题是我遇到了速度问题。
我无法获得与使用浏览器 (Mozilla Firefox) 相同的上传速度,我获得的速度是我从浏览器获得的速度的 1/5。
这是我的 HttpWebRequest 对象的设置
//headers is a NameValueCollection type object,
//Method is a struct GET, POST, HEAD
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.UserAgent = headers["User-Agent"];
request.KeepAlive = false;
request.Accept = headers["Accept"];
request.AllowAutoRedirect = AllowRedirect;
request.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-US,en;q=0.5");
request.Method = Method.ToString();
request.AllowWriteStreamBuffering = false;
request.ReadWriteTimeout = 60000;
我一直启用的一些全局选项
ServicePointManager.Expect100Continue = false;
ServicePointManager.DefaultConnectionLimit = 200;
ServicePointManager.MaxServicePointIdleTime = 2000;
ServicePointManager.MaxServicePoints = 1000;
ServicePointManager.SetTcpKeepAlive(false, 0, 0);
我如何分块发送文件...
if (PostMethod == PostType.MultiPart && uploadFiles.Count > 0)
for (int i = 0; i < uploadFiles.Count; i++)
string fileParam = uploadFiles.GetKey(i);
string tmpFilename = uploadFiles.Get(i);
string tmpData =
string.Format(
"--0\r\nContent-Disposition: form-data; name=\"1\"; filename=\"2\"\r\nContent-Type: 3\r\n\r\n", boundary, fileParam, Path.GetFileName(tmpFilename), MimeType.GetMimeByExtension(Path.GetExtension(tmpFilename)));
byte[] tmpBytes = Encoding.Default.GetBytes(tmpData);
writer.Write(tmpBytes, 0, tmpBytes.Length);
bSent += tmpBytes.Length;
arg.Progress = (int)(bSent * 100 / totalBytes);
arg.Speed = (bSent / sw.Elapsed.TotalSeconds);
OnProgress(arg);
//write the file
int fileBytesRead;
FileStream fileStream = File.Open(tmpFilename, FileMode.Open, FileAccess.Read, FileShare.Read);
// buffer size = 8192
while ((fileBytesRead = fileStream.Read(buffer, 0, BUFFER_SIZE)) > 0)
writer.Write(buffer, 0, fileBytesRead);
bSent += fileBytesRead;
int timeNow = Environment.TickCount;
if (timeNow - lastTime >= 500)
lastTime = timeNow;
arg.Progress = (int)(bSent * 100 / totalBytes);
arg.Speed = (bSent / sw.Elapsed.TotalSeconds);
OnProgress(arg);
tmpBytes = Encoding.Default.GetBytes("\r\n");
writer.Write(tmpBytes, 0, tmpBytes.Length);
bSent += tmpBytes.Length;
arg.Progress = (int)(bSent * 100 / totalBytes);
arg.Speed = (bSent / sw.Elapsed.TotalSeconds);
OnProgress(arg);
我很乐意达到浏览器上传速度的 75%。
【问题讨论】:
与 Firefox 相比,该浏览器是否有任何可能影响该浏览器速度的附加插件。我有一位同事说他们在浏览器中上传速度很慢,让他们使用 Windows 默认地址导航,并且上传速度很快。事实证明,他们有一些插件会窃取数据并造成大量延迟。不过,我会尝试想出更好的东西。 @Greg - 不,我只有 2 个插件,Live HTTP Headers 和 TamperData! WebClient.UploadFile 没有被使用有什么原因吗? @Dan-o - 是的....一些 HTTP 请求与正常格式不同! 你上传的是什么数据?浏览器 (Firefox) 和 WebServer 是否有可能使用http compression?可能你的代码不是。 【参考方案1】:两件事。
您通过分块破坏了 TCP/IP 堆栈的目的。 TCP/IP 旨在处理近乎异步的数据传输。它将自己进行分块并继续发送块,直到完成或达到其未确认的最大块数。如果达到最大块数,它将等待 ACK(确认)继续 - 类似于信号量意识形态期望释放可以“堆叠”,AKA 单个 ACK 包含它收到的最后一个点并且可以“释放” /acknowledge 多个块数据包) - 或请求超时。
通过自己分块,必须完全确认每个块才能发送更多数据,因此您增加了开销。您仍在使用相同的连接,但实际上是在发出多个单独的请求。此外,如果 TCP/IP 块大小不是您的块大小的除数 (YOUR_CHUNK_SIZE % TCP_IP_CHUNK_SIZE != 0),那么您将留下一个延迟的 TCP/IP 块,该块必须超时并解析为伪 ACK;下次它可以在下一个块中得到确认。
2.另一个可能影响性能的选项是使用UseNagleAlgorithm property。当此属性设置为 true 时,TCP/IP 将尝试对 HTTP 连接使用 TCP Nagle 算法。 Nagle 算法在发送 TCP 数据包时聚合数据。在通过网络发送数据之前,它将小消息序列累积成较大的 TCP 数据包。使用 Nagle 算法可以优化网络资源的使用,尽管在某些情况下性能也会降低。通常对于恒定的大容量吞吐量,使用 Nagle 算法实现性能改进。但对于吞吐量较小的应用程序,可能会出现性能下降。
应用程序通常不需要更改默认值 UseNagleAlgorithm 属性设置为 true。然而,如果一个 应用程序正在使用低延迟连接,设置它可能会有所帮助 属性为 false。
来自 MSDN:HttpWebRequest Class (System.Net)
【讨论】:
【参考方案2】:这是我们可以提高上传速度的各种选项:-
http://bytes.com/topic/asp-net/answers/440179-how-speed-up-file-upload-2-0-a
在配置文件中用于大文件:---
把这个写在 web config system.web>
httpRuntime maxRequestLength="2097151"
这可能有助于在 IIS 7.0 中找到解决方案
把这个写在 web config system.web>httpModules
**add name="ITHitPutUploadProgressAndResumeModule" type="ITHit.WebDAV.Server.ResumableUpload.PutUploadProgressAndResumeModule, ITHit.WebDAV.Server"**
【讨论】:
它不是一个网络应用程序,它的WinForm
【参考方案3】:
我通过搜索这个网站找到了答案。它似乎与".NET HttpWebRequest Speed versus Browser" 重复。
从那里发布的答案:
“第一次请求页面时,.net 会尝试检测代理设置。解决方案是传入一个空的 WebProxy 对象。这样它只会连接到远程服务器,而不是自动检测代理服务器。” - Markos
尝试添加
request.Proxy = new WebProxy();
【讨论】:
我设置了request.Proxy = null
,另外还有上传速度的问题,我必须上传大文件,比如 2 GB 文件,mozilla firefox 快 3 倍!
问题是上传速度,如果连接延迟几微秒对我来说没问题,但我需要更好的上传速度!
抱歉,这对您不起作用。我会尝试自己重新创建问题。
您是否尝试过将 ServicePointManager 值保留为默认值? DefaultConnectionLimit、MaxServicePointIdleTime 和 MaxServicePoints 可能会限制您的吞吐量。
另外,你可能想看看***.com/questions/7666268/…以上是关于上传速度问题:HttpWebRequest [重复]的主要内容,如果未能解决你的问题,请参考以下文章
上传图像多部分表单 HTTPWebRequest - 将图像数据转换为字符串?
使用 HttpWebRequest 通过 PUT 上传文件时出错
使用 HttpWebRequest,将文件上传到 SharePoint 时,WebResponse 是未编译的 aspx 页面