您的位置:首页 > 理论基础 > 计算机网络

纯vc sdk实现http post 方式上传数据到web服务器

2014-02-13 14:30 756 查看
转载留下有用:纯vc sdk实现http post 方式上传数据到web服务器

引用url : /article/2024107.html

刚开始的时候想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格式
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐