转载留下有用:纯vc sdk实现http post 方式上传数据到web服务器
引用url : http://blog.youkuaiyun.com/chinafe/article/details/14643607
刚开始的时候想google一个合适的代码.但是非常失望,可能我的搜索技巧不够好,找到的几个代码都是存在这样或那样的问题
要么就是MFC实现,总之是不能满足自己的要求,所以在找了n多代码浪费了大量时间的情况下 还是自己写吧 这样的程序没什么
太大的意思,写一次以后拷贝着用就可以了 所以贴这里备用吧
流程:
1:获得文件内容
2:构造http头备用
3:构造http尾备用
4:与http建立连接
5:发送...
6:提交
要点:
1:http头的构造
// upload.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include <windows.h>
#include <string>
#include <stdlib.h>
#include <Wininet.h>
#include <TCHAR.H>
using namespace std ;
#pragma comment(lib,"Wininet.lib")
string MakeRequestHeaders(string &strBoundary)
{
string strData;
strData += _T("Content-Type: multipart/form-data; boundary="); //二进制文件传送Content-Type类型为: multipart/form-data
strData += strBoundary;
strData +="/r/n";
return strData;
}
string MakePreFileData(string &strBoundary, string &strFileName, int iRecordID)
{
//
string strData;
strData += _T("--");
strData += strBoundary;
strData += _T("/r/n");
strData += _T("Content-Disposition: form-data; name=/"file1/"; filename=/""); //必备1:Path
strData += strFileName;
strData += _T("/"");
strData += _T("/r/n");
strData += _T("Content-Type: image/pjpeg"); //必备2:Type
strData += _T("/r/n/r/n");
return strData;
}
string MakePostFileData(string &strBoundary)
{
string strData;
strData = _T("/r/n");
strData += _T("--");
strData += strBoundary;
strData += _T("/r/n");
strData += _T("Content-Disposition: form-data; name=/"submitted/"");
strData += _T("/r/n/r/n");
strData += _T("hello");
strData += _T("/r/n");
strData += _T("--");
strData += strBoundary;
strData += _T("--");
strData += _T("/r/n");
return strData;
}
//文件长度与文件内容
typedef struct _FileInfo
{
DWORD nFileLen;
DWORD nFileHighLen;
LPSTR FileBuf;
}FileInfo,*pFileInfo;
BOOL GetFileInfo(OUT FileInfo &BinaryInfo, IN string FilePath)
{
BOOL nRet = FALSE;
HANDLE hFile;
DWORD nBytesRead;
hFile = CreateFile(FilePath.c_str(),
GENERIC_ALL, // open for reading
FILE_SHARE_READ, // share for reading
NULL, // no security
OPEN_EXISTING, // existing file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template %
if (hFile == INVALID_HANDLE_VALUE)
{
return nRet;
}
BinaryInfo.nFileLen = GetFileSize(hFile,&BinaryInfo.nFileHighLen);
BinaryInfo.FileBuf = new char[BinaryInfo.nFileLen];
if (!BinaryInfo.FileBuf)
{
CloseHandle(hFile);
return nRet;
}
ZeroMemory(BinaryInfo.FileBuf,BinaryInfo.nFileLen);
if (!ReadFile(hFile, BinaryInfo.FileBuf, BinaryInfo.nFileLen, &nBytesRead, NULL))
{
CloseHandle(hFile);
return nRet;
}
CloseHandle(hFile);
nRet = TRUE;
return nRet;
}
/*
* 本地路径 服务器地址 服务器路径 数据分割信息 端口
* 通过以上传入信息 将二进制数据传入web服务器
*
*/
BOOL Upload(IN string& FilePath,IN string& ServerName,IN string& ObjectName, IN string& HTTPBoundary,IN INTERNET_PORT &nPort)
{
BOOL nRet = FALSE;
HINTERNET hInternet; //by InternetOpen
HINTERNET hHttpSession; //by InternetConnect
HINTERNET hHttpRequest; //by HttpOpenRequest
int iRecordID = 1;
DWORD dwTotalLen; //数据包的总长度
//准备工作
int startp = FilePath.find('//');
int namelen = FilePath.length()-startp-1;
string FileName = FilePath;
string strHeaders = MakeRequestHeaders(HTTPBoundary);
string PreFileData = MakePreFileData(HTTPBoundary, FileName, iRecordID);
string PostFileData = MakePostFileData(HTTPBoundary);
//
//1:getFileInfo
FileInfo localJpg;
if (!GetFileInfo(localJpg,FilePath))
{
return FALSE;
}
dwTotalLen = localJpg.nFileLen + PreFileData.length() + PostFileData.length();
//2:init www
hInternet = InternetOpen(_T("lpszAgent"),
INTERNET_OPEN_TYPE_DIRECT,
NULL,
NULL,
0);
if (!hInternet)
{
return nRet;
}
hHttpSession = InternetConnect( hInternet,
ServerName.c_str(),
INTERNET_DEFAULT_HTTP_PORT,
NULL,
NULL,
INTERNET_SERVICE_HTTP,
INTERNET_FLAG_RELOAD,0);
if (hHttpSession == NULL)
{
InternetCloseHandle(hInternet);
return nRet;
}
//3:Opening a Request
hHttpRequest = HttpOpenRequest(hHttpSession, _T("POST"),
ObjectName.c_str(),
HTTP_VERSIONA,
NULL,NULL, INTERNET_FLAG_MAKE_PERSISTENT,1);
if (hInternet == NULL)
{
InternetCloseHandle(hHttpSession);
InternetCloseHandle(hInternet);
return nRet;
}
//4:HttpAddRequestHeaders
if (!HttpAddRequestHeaders(hHttpRequest,strHeaders.c_str(),strHeaders.length(),HTTP_ADDREQ_FLAG_ADD))
{
goto END;
}
//5:HttpSendRequestEx
INTERNET_BUFFERSA buffer;
memset(&buffer, 0, sizeof(buffer));
buffer.dwStructSize = sizeof(buffer);
buffer.dwBufferTotal = dwTotalLen;
if (!HttpSendRequestEx(hHttpRequest,&buffer,NULL,HSR_SYNC | HSR_INITIATE,1))
{
goto END;
}
//6:_A_send http头
DWORD dwNumberOfBytesWritten;
if(!InternetWriteFile(hHttpRequest,PreFileData.c_str(),PreFileData.length(),&dwNumberOfBytesWritten))
{
goto END;
}
if (dwNumberOfBytesWritten != PreFileData.length())
{
goto END;
}
//6:_B_send filedata
if(!InternetWriteFile(hHttpRequest,localJpg.FileBuf,localJpg.nFileLen,&dwNumberOfBytesWritten))
{
goto END;
}
if (dwNumberOfBytesWritten != localJpg.nFileLen)
{
goto END;
}
//6:_C_send Http尾
if(!InternetWriteFile(hHttpRequest,PostFileData.c_str(),PostFileData.length(),&dwNumberOfBytesWritten))
{
goto END;
}
if (dwNumberOfBytesWritten != PostFileData.length())
{
goto END;
}
//7:完成提交 必不可少
HttpEndRequest(hHttpRequest,NULL,HSR_SYNC,1);
END:
InternetCloseHandle(hHttpRequest);
InternetCloseHandle(hHttpSession);
InternetCloseHandle(hInternet);
return nRet;
}
int main(int argc, char* argv[])
{
string FilePath = _T("C://test//16.jpg");; //本地文件路径
string ServerName = _T("www.baidu.com"); //服务器地址
string ObjectName = _T("//test//upload//upload.asp"); //服务器文件对象
string HTTPBoundary = _T("---------------------------7db29f2140360"); //边界值:要求不严格
INTERNET_PORT nPort = 80; //端口
Upload(FilePath,ServerName,ObjectName,HTTPBoundary,nPort);
return 0;
}
补充:在实验过程中,在服务器要求不严格的情况下,buffer的内容可以自定义,而不一定需要完全符合jpg...的格式,但是
Content-Disposition: form-data; name=/"file1/"; filename=/"jj.yy'")这个地方filename的后缀必须是jpg格式