您的位置:首页 > 理论基础 > 计算机网络

(转)利用HttpWebRequest上传文件应该注意的问题

2009-04-08 16:00 627 查看
最近,在做一个Online Video的公司内部系统时,遇到一个利用HttpWebRequest上传文件时的问题,现象如下:
1、上传30M以下的文件速度很快,大概2-3m。
2、上传90-100M的文件速度在3-5m。
3、上传30M-90M这个区间的任意大小的文件都失败,用时100-101m,错误描述:The operation is time out。
4、将同样的文件用相同的程序,放在另外一台机器上work一切正常。
这个错误是framwork底层抛出来的,若根据这个错误描述查找问题是无法真正解决问题的。
首先,我将代码show出来,大家看看有没有问题:

private static void UploadFile(Stream postedStream, string fileName,
string uploadURL, string fileGroup, string fileType,
string specialPath, string userName, string uploadType)
{
if (string.IsNullOrEmpty(uploadURL))
throw new Exception("Upload Web URL Is Empty.");

HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uploadURL);

//Our method is post, otherwise the buffer (postvars) would be useless
webRequest.Method = WebRequestMethods.Http.Post;

// Proxy setting
WebProxy proxy = new WebProxy();
proxy.UseDefaultCredentials = true;
webRequest.Proxy = proxy;

//We use form contentType, for the postvars.
webRequest.ContentType = "application/x-www-form-urlencoded";

webRequest.Headers.Add("FileGroup", fileGroup);
webRequest.Headers.Add("FileType", fileType);
webRequest.Headers.Add("UploadType", uploadType);
webRequest.Headers.Add("FileName", fileName);
webRequest.Headers.Add("UserName", userName);
webRequest.Headers.Add("SpecialFolderPath", specialPath);

using (Stream requestStream = webRequest.GetRequestStream())
{
FileUtility.CopyStream(postedStream, requestStream);
}
try
{
webRequest.GetResponse().Close();
}
catch (WebException ex)
{
HttpWebResponse response = ex.Response as HttpWebResponse;
if (response != null)
{
throw new WebException(response.StatusDescription, ex);
}

throw ex;
}
catch (Exception exception)
{
throw exception;
}
}

下面,我们来分析上述的现象,发现根本无法找到问题的根本,一头雾水。首先,可以肯定失败的原因是和文件的大小有关的,但是,发生错误的文件大小却是在一个区间段里的,这就无法解释了。然后,我们发现time out的时间都是刚刚超出100m,具体在100-101m之内;这个时间是在需要发送的Request里设的:
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uploadURL);
....
webRequest.Timeout = 1000;//默认为100m,单位为毫秒
那我们就决定将这个时间设的更长一些,但是,根本没用。其实,我们能基本肯定问题不是在这里,因为在上传90M这么大的文件都能很轻易成功,根据这点我们就有理由怀疑问题不是在这里。但是,这种莫名的问题让我们无法理解,接着,我们就像没头苍蝇一样,将所有可以设置time out的地方都设了,比如IIS,接受上传的WebSite里的config里,结果,大家可想而知。
在代码层面我们已经找不到任何办法了,然后,我们只能怀疑是这台服务器的环境有问题,就把问题抛给了公司的IT。可怜了这些IT,怎么可能找到问题!
后来,美国的同事与微软的工作人员一起联调,终于发现了问题的所在,是我们在发送Request的时候没有精确的指定这个Request的ContentLength,导致Framework底层无法知道你什么时候需要终止这个Request,我们只要在上面的代码中增加这段话:
...
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.ContentLength = postedStream.Length;
...
经过测试,发现果然是这个原因。但是,我们就有个问题,微软为什么不在底层处理好这些呢?我们认为微软在底层更能拿到我们的Request的长度,而且更容易包装,更利于使用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: