【问题标题】:POST upload binary file with wininet in c++在 C++ 中使用 wininet POST 上传二进制文件
【发布时间】:2012-07-07 06:39:11
【问题描述】:

我已经得到了这个Upload file via POST -example 来处理 .txt 文件。但是,我仍然缺乏对二进制文件执行相同操作的方法。

有人可以说明如何做到这一点吗?我在整个互联网上浏览了大约 100 多页的人问这个非常相似的问题......许多这些问题都在这个网站上,但没有一个有任何好的答案。 Codeproject 有一些方法,但它们似乎基于 MFC/ATL,我不能使用这些方法。

这个问题似乎非常困难。 :D 所以请有人回答,非常请。你会帮我和很多其他人一个忙。 :)

【问题讨论】:

  • 从浏览器上传二进制文件很困难……在 C 语言中,您只需将二进制数据放在 HTTP 标头后面的两个换行符之后。您链接到的示例将Content-Type 设置为image/jpeg,这是一种二进制格式……什么不工作还是你?此外,multipart/form-data 可能会使事情变得不必要地复杂化。您要上传到哪种服务?
  • 你控制服务器部分吗?如果不是,那么数据的预期 MIME 类型是什么 - 表单或多部分?与文本文件相比,二进制文件有什么特别之处——您只是不确定如何编码非 ASCII 字节?
  • 通过基本的html表单上传,比如php平台上的tizag.com/phpT/fileupload.php。当我尝试使用该脚本上传图像时,图像会通过,但图像的大小只有 4 个字节(iirc),所以我认为我的问题是我无法处理编码非 ASCII 字节? :D
  • 看起来家伙发送了原始数据with this example

标签: c++ post upload binary wininet


【解决方案1】:

下面的代码将使用wininet方法和一个简单的http POST请求上传文件:1.jpg到指定的主机

(name=johndoe and document=1.jpg)

#include<windows.h>
#include<wininet.h>
#include<iostream>

using namespace std;

DWORD rSize,filesize,bytesread,contentlen;

char tmp[2048]; //2Kb Response buffer
char szheaders[1024]; //1kb Header buffer
string chunks; //Server Response

HANDLE hfile;
HINTERNET hOpen2,hConnect2,hReq2;

char szstart[] = "Content-Type: multipart/form-data; boundary=-------------------------acebdf13572468\r\nUser-Agent: Mozilla";
char szData[]    = "---------------------------acebdf13572468\r\nContent-Disposition: form-data; name=\"firstname\"\r\n\r\njohndoe\r\n---------------------------acebdf13572468\r\nContent-Disposition: form-data; name=\"document\"; filename=\"1.jpg\"\r\nContent-Type: application/octet-stream\r\nContent-Transfer-Encoding: binary\r\n\r\n";
char szDataEnd[] = "\r\n---------------------------acebdf13572468--\r\n";

int main()
{

    hfile=CreateFile("1.jpg",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);

    if(hfile != INVALID_HANDLE_VALUE){

    wsprintf(szheaders,szData,"filetoupload","1.jpg");
    hOpen2=InternetOpen(TEXT("Mozilla/5.0"), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
    if(hOpen2){
        hConnect2=InternetConnect(hOpen2, TEXT("www.example.com"), INTERNET_DEFAULT_HTTPS_PORT, TEXT(""), TEXT(""), INTERNET_SERVICE_HTTP, 0, 0);
        if(hConnect2){

           hReq2=HttpOpenRequest(hConnect2, TEXT("POST"), TEXT("/your_path/index.php"), TEXT("HTTP/1.1"),NULL,NULL, INTERNET_FLAG_SECURE | INTERNET_FLAG_RELOAD | INTERNET_FLAG_IGNORE_CERT_CN_INVALID |INTERNET_FLAG_IGNORE_CERT_DATE_INVALID, 0);
           if(hReq2){

                filesize=GetFileSize(hfile,NULL);
                contentlen=lstrlen(szheaders)+filesize+lstrlen(szDataEnd);

                LPBYTE pbuf=(LPBYTE)malloc(contentlen);
                CopyMemory(&pbuf[0],szheaders,lstrlen(szheaders));

                ReadFile(hfile,&pbuf[lstrlen(szheaders)],filesize,&bytesread,NULL);
                CopyMemory(&pbuf[lstrlen(szheaders)+filesize],szDataEnd,lstrlen(szDataEnd));

                BOOL status =  HttpSendRequest(hReq2,szstart,lstrlen(szstart),pbuf,contentlen);
                if (status){
                    chunks="";
                    while(InternetReadFile(hReq2, tmp, 2048, &rSize) && rSize > 0)
                    {
                        tmp[rSize] = '\0';
                        chunks += tmp;
                    }
                    cout << chunks;
                    //Prints Server response
                }
                    CloseHandle(hfile);
                    free(pbuf);
            } 
            InternetCloseHandle(hReq2);
        }
        InternetCloseHandle(hConnect2);
    }
    InternetCloseHandle(hOpen2);
    }

}
 

g++ test.cpp -o test.exe -lwininet

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-31
    • 1970-01-01
    • 2015-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多