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

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

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