使用httpSendRequest c ++上传文件
Posted
技术标签:
【中文标题】使用httpSendRequest c ++上传文件【英文标题】:uploading files using httpSendRequest c++ 【发布时间】:2012-04-12 19:59:52 【问题描述】:我正在尝试通过 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 的文件发送到 Internet 服务器。 (HttpOpenRequest 失败) 有没有更好的上传文件的方法?
【问题讨论】:
【参考方案1】:警告:这些天我的 Wininet 非常生锈。
我想知道您是否应该自己设置“Content-Length”标头。您的代码似乎假设 a)您正在发出 HTTP/1.0 请求或 b)HttpSendRequest
将为您添加标头(我认为不会)。
无论服务器被告知传入的请求有多大,如果 IIS 的默认配置不能快速确定请求大小,它都会拒绝它。
我的猜测是,如果您使用HttpSendRequest
函数的lpszHeaders
和dwHeadersLength
参数来包含适当的“Content-Length”标头,问题将得到解决。
【讨论】:
感谢您的回答,我会尝试,但奇怪的是为什么它在本地工作(因为不涉及 IIS)并且当我们通过 IIS 时,事情发生了变化...... @CnativeFreak:这听起来对我来说是正确的,我猜测 IIS 拒绝请求是为了防止流氓或恶意请求对服务器造成不良影响,例如 DOS 攻击。 Cassini 开发服务器不需要这种保护,因此您在没有 IIS 的情况下进行本地调试也可以正常工作。 我做了以下 char headers[255]; memset(标题,0,255); sprintf(headers,"Content-Length: %d",buffSize); if(!HttpSendRequest(httpRequest, headers, strlen(headers), buff, buffSize)) 但 HttpSendRequest 仍然退出,没有错误非常快【参考方案2】:您收到什么错误?我的意思是 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));
【讨论】:
我试过了,好像只能发800KB左右,1MB都发不出去 我读到它们在调试器中检查了它们,它们是 30000 然后将它们设置为 600000 DWORD dwReceiveTimeOut; DWORD dwSendTimeOut; DWORD 大小=sizeof(dwReceiveTimeOut); InternetQueryOption(httpRequest, INTERNET_OPTION_RECEIVE_TIMEOUT, &dwReceiveTimeOut, &size); InternetQueryOption(httpRequest, INTERNET_OPTION_SEND_TIMEOUT, &dwSendTimeOut, &size); dwReceiveTimeOut=600000; dwSendTimeOut=600000; InternetSetOption(httpRequest, INTERNET_OPTION_RECEIVE_TIMEOUT, &dwReceiveTimeOut,size); InternetSetOption(httpRequest, INTERNET_OPTION_SEND_TIMEOUT, &dwSendTimeOut, size);以上是关于使用httpSendRequest c ++上传文件的主要内容,如果未能解决你的问题,请参考以下文章
使用 FBSDKProfileExpressionKit 上传 Facebook 个人资料图片 - 目标 c