求助:使用wininet,http post方式上传文件到服务器

xiaodahero 2011-03-18 10:44:20
使用wininet,http post方式上传文件到服务器,代码执行成功了,但是服务器上没有生成预期文件,请问可能的原因是什么?
我将下面代码中的POST方式改为PUT方式后能够成功在服务器上上传代码,但POST方式不行,是为什么呢?
是不是POST方式时,服务器端也需要单独编写接收代码?
附上代码:
#include<windows.h>
#include<wininet.h>
#include<iostream>


DWORD dwNumKSent;
DWORD dwNumKToSend;
DWORD dwNumBytesComplete = 0;
char lpOutBuf[1024];
HANDLE hConnectedEvent, hRequestCompleteEvent;
HINTERNET hInstance, hConnect, hRequest;
char *lpszUrl, *lpszServer;


BOOL bAllDone = FALSE;


void __stdcall Callback(HINTERNET hInternet,
DWORD dwContext,
DWORD dwInternetStatus,
LPVOID lpStatusInfo,
DWORD dwStatusInfoLen);


void main(int argc, char *argv[])
{


dwNumKToSend = 256;


FillMemory(lpOutBuf, 1024, 'A');
//创建两个Event Obj对象,匿名的、自动重置、初始无信号状态
hConnectedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
hRequestCompleteEvent = CreateEvent(NULL, FALSE, FALSE, NULL);


//step 1,创建HTTP网络连接
hInstance = InternetOpen("sendreqexasync",
INTERNET_OPEN_TYPE_PRECONFIG,
NULL,
NULL,
INTERNET_FLAG_ASYNC); //异步的
if (hInstance == NULL)
{
std::cout << "InternetOpen failed, error " << GetLastError();
return;
}


//step 2,设置回调
if (InternetSetStatusCallback(hInstance,
(INTERNET_STATUS_CALLBACK)&Callback) == INTERNET_INVALID_STATUS_CALLBACK)
{
std::cout << "InternetSetStatusCallback failed, error " << GetLastError();
return;
}


//step 3,创建网络连接
hConnect = InternetConnect(hInstance,
//"www.foo.com", //服务器的地址
"127.0.0.1", //服务器的地址
//"ttplayer.qianqian.com",
INTERNET_DEFAULT_HTTP_PORT, //端口号
NULL,
NULL,
INTERNET_SERVICE_HTTP, //采用HTTP协议方式连接
0,
1);//回调函数中的case判断
if (hConnect == NULL)
{
if (GetLastError() != ERROR_IO_PENDING)
{
std::cout << "InternetConnect failed, error " << GetLastError();
return;
}
//等待回调函数,完成hConnect句柄的创建
WaitForSingleObject(hConnectedEvent, INFINITE);
}


//step 4,创建一个HTTP请求
hRequest = HttpOpenRequest(hConnect,
"PUT", //命名字,采用POST协议
//"/postfolder/upload.exe", //命令对象
"/Up/abc10.txt", //命令对象
//"/Up/upload.exe", //命令对象
//"/otherdown/alladin/ttpsetup2.exe",
NULL,
NULL,
NULL,
INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE,
2);//回调函数中的case判断
if (hRequest == NULL)
{
if (GetLastError() != ERROR_IO_PENDING)
{
std::cout << "HttpOpenRequest failed, error " << GetLastError();
return;
}
//等待回调函数,完成hRequest句柄的创建
WaitForSingleObject(hRequestCompleteEvent, INFINITE);
}


//step 5,发送HTTP请求
INTERNET_BUFFERS IntBuff;


FillMemory(&IntBuff, sizeof(IntBuff), 0);
IntBuff.dwStructSize= sizeof(IntBuff);
IntBuff.dwBufferTotal = 1024*dwNumKToSend; //要发送的总数据长度
IntBuff.lpcszHeader = "Content-Type: text/text\r\n";
IntBuff.dwHeadersLength = lstrlen(IntBuff.lpcszHeader);

//HttpSendRequest(hResourceHandle, NULL, 0, NULL, 0);


if (!HttpSendRequestEx(hRequest,
&IntBuff,
NULL,
0,
2))//回调函数中的case判断
{
if (GetLastError() != ERROR_IO_PENDING)
{
std::cout << "HttpSendRequestEx failed, error " << GetLastError();
return;
}
std::cout << "HttpSendRequestEx called successfully" << std::endl;
std::cout.flush();


WaitForSingleObject(hRequestCompleteEvent, INFINITE);
}


//step 6,往服务器上写数据
for (dwNumKSent = 0; dwNumKSent < dwNumKToSend; dwNumKSent++)
{
DWORD dwBytesWritten;


if(!InternetWriteFile(hRequest,
lpOutBuf,
1024,
&dwBytesWritten))
{
if (GetLastError() != ERROR_IO_PENDING)
{
std::cout << "InternetWriteFile failed, error " << GetLastError();
return;
}
else
{
std::cout << "InternetWriteFile completing asynchronously" << std::endl;
std::cout.flush();
WaitForSingleObject(hRequestCompleteEvent, INFINITE);
}
}
}


std::cout << "Calling HttpEndRequest" << std::endl;
std::cout.flush();
if (!HttpEndRequest(hRequest, NULL, HSR_INITIATE, 2))
{
if (GetLastError() == ERROR_IO_PENDING)
{
std::cout << "HttpEndRequest called" << std::endl;
std::cout.flush();
WaitForSingleObject(hRequestCompleteEvent, INFINITE);
}
else
{
std::cout << "HttpEndRequest failed, error " << GetLastError() << std::endl;
return;
}
}

}




/////这是回调函数,重点看下它的写法
void __stdcall Callback(HINTERNET hInternet,
DWORD dwContext, //对应函数的dwContext值,用于指明现在是哪个函数产生的回调
DWORD dwInternetStatus,
LPVOID lpStatusInfo,
DWORD dwStatusInfoLen)
{
std::cout << "Callback dwInternetStatus: " << dwInternetStatus << " Context: " << dwContext << std::endl;
std::cout.flush();


switch(dwContext)
{
case 1: // Connection handle
if (dwInternetStatus == INTERNET_STATUS_HANDLE_CREATED)
{
INTERNET_ASYNC_RESULT *pRes = (INTERNET_ASYNC_RESULT *)lpStatusInfo;
//当您收到此通知时,
//请从 INTERNET_ASYNC_RESULT 结构的 dwResult 成员保存该句柄值
//您不能使用此句柄,直到您收到了 INTERNET_STATUS_REQUEST_COMPLETE 通知
hConnect = (HINTERNET)pRes->dwResult;
std::cout << "Connect handle created" << std::endl;
std::cout.flush();
SetEvent(hConnectedEvent);
}
break;
case 2: // Request handle
switch(dwInternetStatus)
{
case INTERNET_STATUS_HANDLE_CREATED:
{
INTERNET_ASYNC_RESULT *pRes = (INTERNET_ASYNC_RESULT *)lpStatusInfo;
hRequest = (HINTERNET)pRes->dwResult;
std::cout << "Request handle created" << std::endl;
std::cout.flush();
}
break;
case INTERNET_STATUS_REQUEST_SENT:
{
DWORD *lpBytesSent = (DWORD*)lpStatusInfo;
std::cout << "Bytes Sent: " << *lpBytesSent << std::endl;
dwNumBytesComplete += *lpBytesSent;
}
break;
case INTERNET_STATUS_REQUEST_COMPLETE:
{
INTERNET_ASYNC_RESULT *pAsyncRes = (INTERNET_ASYNC_RESULT *)lpStatusInfo;
std::cout << "Function call finished" << std::endl;
std::cout << "dwResult: " << pAsyncRes->dwResult << std::endl;
std::cout << "dwError: " << pAsyncRes->dwError << std::endl;
std::cout.flush();
SetEvent(hRequestCompleteEvent);
}
break;
case INTERNET_STATUS_RECEIVING_RESPONSE:
std::cout << "Receiving Response" << std::endl;
std::cout.flush();
break;
case INTERNET_STATUS_RESPONSE_RECEIVED:
{
DWORD *dwBytesReceived = (DWORD*)lpStatusInfo;
std::cout << "Received " << *dwBytesReceived << std::endl;
std::cout.flush();
}
}
}
}
...全文
226 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaodahero 2011-03-18
  • 打赏
  • 举报
回复
此程序的目的是,上传文件到服务器。
还有PUT和POST方式,区别在哪里?
xiaodahero 2011-03-18
  • 打赏
  • 举报
回复
以上代码的PUT版本,运行正常,POST方式,能够运行成功,可是服务器端没生成文件

64,652

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧