求助:使用wininet,http post方式上传文件到服务器
使用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();
}
}
}
}