我正在尝试通过POST请求(c ++和winapi)将文件发送到HTTP服务器,步骤:
// Read file into "buff" and file size into "buffSize"
....
....
....
HINTERNET internetRoot;
HINTERNET httpSession;
HINTERNET httpRequest;
internetRoot = InternetOpen(agent_info, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, NULL);
//Connecting to the http server
httpSession = InternetConnect(internetRoot, IP,PORT_NUMBER, NULL, NULL, INTERNET_SERVICE_HTTP, NULL, NULL);
//Creating a new HTTP POST request to the default resource on the server
httpRequest = HttpOpenRequest(httpSession, TEXT("POST"), TEXT("/Post.aspx"), NULL, NULL, NULL, INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE, NULL);
//Send POST request
HttpSendRequest(httpRequest, NULL, NULL, buff, buffSize);
//Closing handles...
在服务器中,我使用此代码(asp.net)
收到文件Stream httpStream;
try
{
httpStream = request.RequestContext.HttpContext.Request.InputStream;
}
catch (HttpException)
{
return;
}
byte[] tmp = new byte[httpStream.Length];
int bytesRead = httpStream.Read(tmp, 0, 1024 * 1024);
int totalBytesRead = bytesRead;
while (bytesRead > 0)
{
bytesRead = httpStream.Read(tmp, totalBytesRead, 1024 * 1024);
totalBytesRead += bytesRead;
}
httpStream.Close();
httpStream.Dispose();
//Save "tmp" to file...
我可以在本地服务器(visual studio asp服务器)上发送大文件,但我无法将超过1 MB的文件发送到互联网服务器。 (HttpOpenRequest失败) 是否有更好的上传文件的方法?
答案 0 :(得分:1)
警告:这些天我的Wininet非常生疏。
我想知道你是否应该自己设置“Content-Length”标题。您的代码似乎假设a)您正在发出HTTP / 1.0请求或b)HttpSendRequest
将为您添加标头(我认为它不会这样做)。
如果无法告知服务器传入请求有多大,IIS的默认配置将拒绝它,如果它无法快速确定请求大小本身。
我的猜测是,如果您使用lpszHeaders
函数的dwHeadersLength
和HttpSendRequest
参数来包含相应的“内容长度”标题,则问题将得到解决。
答案 1 :(得分:1)
你收到什么错误?我的意思是GetLastError()返回什么?如果你发送文件800KB然后它工作正常吗?我真的不明白,因为HttpOpenRequest不知道数据的大小。
也许超时?但这意味着HttpSendRequest实际上失败了。它可能会缓冲所有数据,但由于大小很大,因此需要的时间比超时允许的时间长。
使用以下代码查询当前超时(以毫秒为单位):
InternetQueryOption(h, INTERNET_OPTION_RECEIVE_TIMEOUT, &dwReceiveTimeOut, sizeof(dwReceiveTimeOut));
InternetQueryOption(h, INTERNET_OPTION_SEND_TIMEOUT, &dwSendTimeOut, sizeof(dwSendTimeOut));
然后设置新的:
InternetSetOption(h, INTERNET_OPTION_RECEIVE_TIMEOUT, &dwNewReceiveTimeOut, sizeof(dwNewReceiveTimeOut));
InternetSetOption(h, INTERNET_OPTION_SEND_TIMEOUT, &dwNewSendTimeOut, sizeof(dwNewSendTimeOut));