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

分类: C~VC SDK~MFC Http windows 2011-02-26 01:28 1132人阅读 评论(1) 收藏 举报

刚开始的时候想google一个合适的代码.但是非常失望,可能我的搜索技巧不够好,找到的几个代码都是存在这样或那样的问题

要么就是MFC实现,总之是不能满足自己的要求,所以在找了n多代码浪费了大量时间的情况下 还是自己写吧  这样的程序没什么

太大的意思,写一次以后拷贝着用就可以了 所以贴这里备用吧

 

流程:

       1:获得文件内容

       2:构造http头备用

       3:构造http尾备用

       4:与http建立连接

       5:发送...

       6:提交

 

要点:

      1:http头的构造

 

  1. // upload.cpp : Defines the entry point for the console application.  
  2. #include "stdafx.h"  
  3. #include <windows.h>  
  4. #include <string>  
  5. #include <stdlib.h>  
  6. #include <Wininet.h>  
  7. #include <TCHAR.H>  
  8. using namespace std ;  
  9. #pragma comment(lib,"Wininet.lib")    
  10. string MakeRequestHeaders(string &strBoundary)  
  11. {  
  12.     string strData;  
  13.       
  14.     strData += _T("Content-Type: multipart/form-data; boundary=");    //二进制文件传送Content-Type类型为: multipart/form-data  
  15.     strData += strBoundary;  
  16.     strData +="/r/n";  
  17.     return strData;  
  18. }  
  19. string MakePreFileData(string &strBoundary, string &strFileName, int iRecordID)  
  20. {  
  21.     //  
  22.     string strData;  
  23.       
  24.     strData += _T("--");  
  25.     strData += strBoundary;  
  26.     strData += _T("/r/n");  
  27.     strData += _T("Content-Disposition: form-data; name=/"file1/"; filename=/"");  //必备1:Path  
  28.     strData += strFileName;                                           
  29.     strData += _T("/"");  
  30.     strData += _T("/r/n");  
  31.     strData += _T("Content-Type: image/pjpeg");                                     //必备2:Type  
  32.       
  33.     strData += _T("/r/n/r/n");  
  34.       
  35.     return strData;  
  36. }  
  37. string MakePostFileData(string &strBoundary)  
  38. {  
  39.     string strData;  
  40.       
  41.     strData = _T("/r/n");     
  42.     strData += _T("--");  
  43.     strData += strBoundary;  
  44.     strData += _T("/r/n");  
  45.     strData += _T("Content-Disposition: form-data; name=/"submitted/"");  
  46.     strData += _T("/r/n/r/n");  
  47.     strData += _T("hello");  
  48.     strData += _T("/r/n");  
  49.     strData += _T("--");  
  50.     strData += strBoundary;  
  51.     strData += _T("--");  
  52.     strData += _T("/r/n");  
  53.     return strData;  
  54. }  
  55. //文件长度与文件内容   
  56. typedef struct _FileInfo  
  57. {  
  58.     DWORD  nFileLen;  
  59.     DWORD  nFileHighLen;              
  60.     LPSTR FileBuf;  
  61. }FileInfo,*pFileInfo;  
  62. BOOL GetFileInfo(OUT FileInfo &BinaryInfo, IN string FilePath)  
  63. {  
  64.     BOOL   nRet = FALSE;  
  65.     HANDLE hFile;   
  66.     DWORD nBytesRead;  
  67.     hFile = CreateFile(FilePath.c_str(),            
  68.         GENERIC_ALL,              // open for reading   
  69.         FILE_SHARE_READ,           // share for reading   
  70.         NULL,                      // no security   
  71.         OPEN_EXISTING,             // existing file only   
  72.         FILE_ATTRIBUTE_NORMAL,     // normal file   
  73.         NULL);                     // no attr. template %  
  74.       
  75.     if (hFile == INVALID_HANDLE_VALUE)   
  76.     {   
  77.         return nRet;  
  78.     }   
  79.       
  80.     BinaryInfo.nFileLen = GetFileSize(hFile,&BinaryInfo.nFileHighLen);  
  81.     BinaryInfo.FileBuf = new char[BinaryInfo.nFileLen];  
  82.     if (!BinaryInfo.FileBuf)  
  83.     {  
  84.         CloseHandle(hFile);  
  85.         return nRet;  
  86.     }  
  87.     ZeroMemory(BinaryInfo.FileBuf,BinaryInfo.nFileLen);  
  88.     if (!ReadFile(hFile, BinaryInfo.FileBuf, BinaryInfo.nFileLen, &nBytesRead, NULL))  
  89.     {  
  90.         CloseHandle(hFile);  
  91.         return nRet;  
  92.     }  
  93.       
  94.     CloseHandle(hFile);  
  95.     nRet = TRUE;  
  96.     return nRet;  
  97. }  
  98. /* 
  99.  * 本地路径 服务器地址 服务器路径 数据分割信息 端口 
  100.  * 通过以上传入信息 将二进制数据传入web服务器 
  101.  * 
  102. */  
  103. BOOL Upload(IN string& FilePath,IN string& ServerName,IN string& ObjectName, IN string& HTTPBoundary,IN INTERNET_PORT &nPort)  
  104. {  
  105.     BOOL      nRet = FALSE;  
  106.     HINTERNET hInternet;                //by   InternetOpen  
  107.     HINTERNET hHttpSession;             //by   InternetConnect  
  108.     HINTERNET hHttpRequest;             //by   HttpOpenRequest  
  109.     int       iRecordID = 1;  
  110.     DWORD     dwTotalLen;               //数据包的总长度  
  111.     //准备工作  
  112.     int    startp   = FilePath.find('//');  
  113.     int    namelen  = FilePath.length()-startp-1;  
  114.     string FileName = FilePath;  
  115.       
  116.     string strHeaders   = MakeRequestHeaders(HTTPBoundary);  
  117.     string PreFileData  = MakePreFileData(HTTPBoundary, FileName, iRecordID);  
  118.     string PostFileData = MakePostFileData(HTTPBoundary);  
  119.     //  
  120.     //1:getFileInfo  
  121.     FileInfo localJpg;  
  122.     if (!GetFileInfo(localJpg,FilePath))  
  123.     {  
  124.         return FALSE;  
  125.     }  
  126.     dwTotalLen = localJpg.nFileLen + PreFileData.length() + PostFileData.length();  
  127.     //2:init www  
  128.     hInternet = InternetOpen(_T("lpszAgent"),  
  129.                              INTERNET_OPEN_TYPE_DIRECT,   
  130.                              NULL,  
  131.                              NULL,  
  132.                              0);  
  133.       
  134.     if (!hInternet)  
  135.     {  
  136.         return nRet;  
  137.     }  
  138.       
  139.     hHttpSession = InternetConnect( hInternet,  
  140.                                     ServerName.c_str(),  
  141.                                     INTERNET_DEFAULT_HTTP_PORT,  
  142.                                     NULL,  
  143.                                     NULL,  
  144.                                     INTERNET_SERVICE_HTTP,  
  145.                                     INTERNET_FLAG_RELOAD,0);       
  146.       
  147.     if (hHttpSession == NULL)  
  148.     {  
  149.           
  150.         InternetCloseHandle(hInternet);  
  151.         return nRet;  
  152.     }  
  153.     //3:Opening a Request  
  154.     hHttpRequest = HttpOpenRequest(hHttpSession, _T("POST"),   
  155.                                    ObjectName.c_str(),  
  156.                                    HTTP_VERSIONA,   
  157.                                    NULL,NULL, INTERNET_FLAG_MAKE_PERSISTENT,1);   
  158.     if (hInternet == NULL)  
  159.     {  
  160.         InternetCloseHandle(hHttpSession);  
  161.         InternetCloseHandle(hInternet);  
  162.         return nRet;  
  163.     }  
  164.     //4:HttpAddRequestHeaders  
  165.     if (!HttpAddRequestHeaders(hHttpRequest,strHeaders.c_str(),strHeaders.length(),HTTP_ADDREQ_FLAG_ADD))  
  166.     {     
  167.         goto END;  
  168.     }  
  169.       
  170.     //5:HttpSendRequestEx  
  171.     INTERNET_BUFFERSA buffer;  
  172.     memset(&buffer, 0, sizeof(buffer));  
  173.     buffer.dwStructSize  = sizeof(buffer);  
  174.     buffer.dwBufferTotal = dwTotalLen;  
  175.     if (!HttpSendRequestEx(hHttpRequest,&buffer,NULL,HSR_SYNC | HSR_INITIATE,1))  
  176.     {  
  177.         goto END;  
  178.     }  
  179.       
  180.     //6:_A_send http头  
  181.     DWORD dwNumberOfBytesWritten;     
  182.     if(!InternetWriteFile(hHttpRequest,PreFileData.c_str(),PreFileData.length(),&dwNumberOfBytesWritten))  
  183.     {  
  184.         goto END;  
  185.     }  
  186.     if (dwNumberOfBytesWritten != PreFileData.length())  
  187.     {  
  188.         goto END;  
  189.     }  
  190.       
  191.     //6:_B_send filedata  
  192.     if(!InternetWriteFile(hHttpRequest,localJpg.FileBuf,localJpg.nFileLen,&dwNumberOfBytesWritten))  
  193.     {  
  194.         goto END;  
  195.     }  
  196.       
  197.     if (dwNumberOfBytesWritten != localJpg.nFileLen)  
  198.     {  
  199.         goto END;  
  200.     }  
  201.     //6:_C_send Http尾  
  202.     if(!InternetWriteFile(hHttpRequest,PostFileData.c_str(),PostFileData.length(),&dwNumberOfBytesWritten))  
  203.     {  
  204.         goto END;  
  205.     }  
  206.       
  207.     if (dwNumberOfBytesWritten != PostFileData.length())  
  208.     {  
  209.         goto END;  
  210.     }  
  211.     //7:完成提交 必不可少  
  212.     HttpEndRequest(hHttpRequest,NULL,HSR_SYNC,1);  
  213. END:  
  214.     InternetCloseHandle(hHttpRequest);  
  215.     InternetCloseHandle(hHttpSession);  
  216.     InternetCloseHandle(hInternet);  
  217.     return nRet;  
  218. }  
  219. int main(int argc, char* argv[])  
  220. {  
  221.     string          FilePath     = _T("C://test//16.jpg");;                             //本地文件路径  
  222.     string          ServerName   = _T("www.baidu.com");                                 //服务器地址  
  223.     string          ObjectName   = _T("//test//upload//upload.asp");                    //服务器文件对象  
  224.     string          HTTPBoundary = _T("---------------------------7db29f2140360");      //边界值:要求不严格  
  225.     INTERNET_PORT   nPort        = 80;                                                  //端口  
  226.     Upload(FilePath,ServerName,ObjectName,HTTPBoundary,nPort);  
  227.     return 0;  
  228. }  
 

补充:在实验过程中,在服务器要求不严格的情况下,buffer的内容可以自定义,而不一定需要完全符合jpg...的格式,但是

C

转载于:https://my.oschina.net/SmileWolf/blog/183097

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
VC实现 HTTPPOST 方式上传文件并获取返回值,可以通过以下步骤实现: 1. 引用 WinINet 库 在 VC 项目中,需要引用 WinINet 库,可以通过以下步骤添加: 在 Solution Explorer 中,右键单击项目,选择 Properties。 在 Property Pages 对话框中,选择 Configuration Properties -> Linker -> Input。 在 Additional Dependencies 中添加 WinINet.lib。 2. 创建 HTTP 连接 使用 InternetOpen 函数创建 HTTP 连接,该函数返回一个 HINTERNET 句柄,用于后续操作: ``` HINTERNET hInternet = InternetOpen(_T("MyApp"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); ``` 其中,第一个参数是应用程序名称,第二个参数指定连接类型,第三个和第四个参数分别为代理服务器的名称和端口号,最后一个参数为可选的标志,如果为 0,则使用默认标志。 3. 创建 HTTP 请求 使用 HttpOpenRequest 函数创建 HTTP 请求,该函数需要传入上一步中创建的 HINTERNET 句柄,返回一个 HINTERNET 句柄,用于后续操作: ``` HINTERNET hHttp = HttpOpenRequest(hInternet, _T("POST"), _T("/upload.php"), NULL, NULL, NULL, INTERNET_FLAG_RELOAD, 0); ``` 其中,第一个参数为上一步中创建的 HINTERNET 句柄,第二个参数指定请求方法,这里使用 POST 方法,第三个参数为上传文件的路径,第四个和第五个参数分别为 HTTP 请求头和请求头的长度,最后一个参数为可选的标志,这里使用 INTERNET_FLAG_RELOAD 标志,表示每次请求都从服务器获取最新的内容。 4. 添加 HTTP 请求头 使用 HttpAddRequestHeaders 函数添加 HTTP 请求头,这里需要添加 Content-Type 和 Content-Length 请求头: ``` TCHAR szContentType[] = _T("Content-Type: multipart/form-data; boundary=***"); HttpAddRequestHeaders(hHttp, szContentType, _tcslen(szContentType), HTTP_ADDREQ_FLAG_ADD); TCHAR szContentLength[256]; sprintf_s(szContentLength, _T("Content-Length: %d"), dwTotalSize); HttpAddRequestHeaders(hHttp, szContentLength, strlen(szContentLength), HTTP_ADDREQ_FLAG_ADD); ``` 其中,第一个参数为上一步中创建的 HINTERNET 句柄,第二个参数为请求头的内容,第三个参数为请求头的长度,最后一个参数为可选的标志,这里使用 HTTP_ADDREQ_FLAG_ADD 标志,表示添加请求头而不是替换。 5. 构建 HTTP 请求正文 使用 HttpSendRequest 函数发送 HTTP 请求,这里需要构建 HTTP 请求正文,即上传文件的数据,可以使用 multipart/form-data 格式,该格式需要指定一个分隔符,每个字段都以分隔符开始,以分隔符结束,字段名和字段值之间用两个换行符分隔,文件数据需要以二进制方式传输,每个文件以分隔符开始,以分隔符结束,文件名和文件数据之间用两个换行符分隔。 ``` TCHAR szBoundary[] = _T("***"); TCHAR szHeader[1024]; sprintf_s(szHeader, _T("--%s\r\nContent-Disposition: form-data; name=\"file\"; filename=\"%s\"\r\nContent-Type: application/octet-stream\r\n\r\n"), szBoundary, szFileName); DWORD dwHeaderSize = strlen(szHeader); TCHAR szFooter[1024]; sprintf_s(szFooter, _T("\r\n--%s--\r\n"), szBoundary); DWORD dwFooterSize = strlen(szFooter); DWORD dwTotalSize = dwHeaderSize + dwFileSize + dwFooterSize; HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwTotalSize); LPBYTE pBuffer = (LPBYTE)GlobalLock(hGlobal); memcpy(pBuffer, szHeader, dwHeaderSize); pBuffer += dwHeaderSize; DWORD dwBytesRead; ReadFile(hFile, pBuffer, dwFileSize, &dwBytesRead, NULL); pBuffer += dwBytesRead; memcpy(pBuffer, szFooter, dwFooterSize); pBuffer += dwFooterSize; GlobalUnlock(hGlobal); HttpSendRequest(hHttp, szContentType, _tcslen(szContentType), hGlobal, dwTotalSize); ``` 其中,第一个参数为上一步中创建的 HINTERNET 句柄,第二个参数为请求头的内容,第三个参数为请求头的长度,第四个参数为上传文件的数据,第五个参数为上传文件的数据长度。 6. 获取 HTTP 响应 使用 InternetReadFile 函数获取 HTTP 响应,这里需要读取 HTTP 响应正文,即服务器返回的数据: ``` BYTE szBuffer[1024]; DWORD dwBytesRead; while (InternetReadFile(hHttp, szBuffer, sizeof(szBuffer), &dwBytesRead) && dwBytesRead > 0) { // 处理读取到的数据 } ``` 其中,第一个参数为上一步中创建的 HINTERNET 句柄,第二个参数为读取数据的缓冲区,第三个参数为缓冲区的长度,第四个参数为读取到的数据长度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值