我正在使用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%的浏览器上传速度,也非常感谢任何帮助。
答案 0 :(得分:6)
我通过搜索这个网站找到了答案。它似乎与".NET HttpWebRequest Speed versus Browser"重复。
从那里发布的答案:
“第一次请求页面时,.net会尝试检测代理设置。解决方案是传入一个空的WebProxy对象。这样它只是连接到远程服务器而不是自动检测代理服务器。” - Markos
尝试添加
request.Proxy = new WebProxy();
答案 1 :(得分:2)
两件事。
您通过分块来破坏TCP / IP堆栈的目的。 TCP / IP旨在处理近乎异步的数据传输。它将执行自己的分块并继续发送块直到它完成或达到其未确认的块的最大数量。如果达到最大块数,它将等待ACK(确认)继续 - 类似于信号量意识形态期望释放可以“堆叠”,AKA单个ACK包含它收到的最后一个点并且可以“释放” /确认多个块数据包) - 或请求超时。
通过自己分块,每个块都必须完全确认才能发送更多数据,这样你就增加了开销。您仍在使用相同的连接,但基本上会发出多个单独的请求。此外,如果TCP / IP块大小不是块大小的除数(YOUR_CHUNK_SIZE%TCP_IP_CHUNK_SIZE!= 0),那么您将留下一个必须超时的延迟TCP / IP块并解析为伪ACK;下次可以在下一个块中得到确认。
可能对性能产生影响的另一个选择是使用UseNagleAlgorithm property。当此属性设置为 true 时,TCP / IP将尝试使用TCP Nagle算法进行HTTP连接。 Nagle算法在发送TCP数据包时聚合数据。它在通过网络发送数据之前将小消息序列累积到更大的TCP数据包中。使用Nagle算法可以优化网络资源的使用,尽管在某些情况下性能也会降低。通常,对于恒定的高容量吞吐量,使用Nagle算法实现性能改进。但对于较小的吞吐量应用,可能会出现性能下降。
应用程序通常不需要更改默认值 UseNagleAlgorithm属性,设置为 true 。但是,如果一个 应用程序正在使用低延迟连接,它可能有助于设置此 属性为 false 。
答案 2 :(得分:0)
以下是使用我们可以提高上传速度的各种选项: -
http://bytes.com/topic/asp-net/answers/440179-how-speed-up-file-upload-2-0-a
在大文件的配置文件中使用它:---
在web config system.web&gt;
中写下此内容httpRuntime maxRequestLength =“2097151”
这可能有助于在IIS 7.0中找到解决方案
在web config system.web&gt; httpModules
中写下这个**add name="ITHitPutUploadProgressAndResumeModule" type="ITHit.WebDAV.Server.ResumableUpload.PutUploadProgressAndResumeModule, ITHit.WebDAV.Server"**