2014-04-22 58 views
0

我是C++環境的新手。我嘗試用C++將圖像文件上傳到PHP服務器。但它不會發送完整的文件。只有我上傳的圖片文件大小爲1 KB。用C++上傳圖片文件

我在SO裏找到了和我一樣的帖子。但我不知道如何將圖像二進制轉換爲base64字符串。我嘗試了另一個解決方案memcpy,它也不起作用。

Upload file via POST

我的C++代碼:

#define _CRT_SECURE_NO_DEPRECATE 
#include <iostream> 
#include <tchar.h> 
#include <Urlmon.h> 
#pragma comment (lib, "Urlmon.lib") 

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

#pragma comment(lib,"wininet.lib") 
#define ERROR_OPEN_FILE  10 
#define ERROR_MEMORY   11 
#define ERROR_SIZE   12 
#define ERROR_INTERNET_OPEN 13 
#define ERROR_INTERNET_CONN 14 
#define ERROR_INTERNET_REQ 15 
#define ERROR_INTERNET_SEND 16 

using namespace cv; 
using namespace std; 

int main() 
{ 
    // Local variables 
    static char *filename = "test.jpg"; //Filename to be loaded 
    static char *filepath = "test.jpg"; //Filename to be loaded 
    static char *type = "text/jpeg"; 
    static TCHAR hdrs[] = "Content-Type: multipart/form-data; boundary=---------------------------7d82751e2bc0858"; 
    static char boundary[] = "-----------------------------7d82751e2bc0858";   //Header boundary 
    static char nameForm[] = "uploadedfile";  //Input form name 
    static char iaddr[] = "server";  //IP address 
    static char url[] = "uploader.php"; 

    char * buffer;     //Buffer containing file + headers 
    char * content;     //Buffer containing file 
    FILE * pFile;     //File pointer 
    long lSize;      //File size 
    size_t result; 
    char *pos; // used in the loop 

    // Open file 
    pFile = fopen(filepath, "rb"); 
    if (pFile == NULL) 
    { 
     printf("ERROR_OPEN_FILE"); 
     getchar(); 
     return ERROR_OPEN_FILE; 
    } 
    printf("OPEN_FILE\n"); 

    // obtain file size: 
    fseek(pFile, 0, SEEK_END); 
    lSize = ftell(pFile); 
    rewind(pFile); 

    // allocate memory to contain the whole file: 
    content = (char*)malloc(sizeof(char)*lSize); 
    if (content == NULL) 
    { 
     printf("ERROR_MEMORY"); 
     getchar(); 
     return ERROR_OPEN_FILE; 
    } 

    printf("MEMORY_ALLOCATED\t \"%d\" \n", lSize); 
    // copy the file into the buffer: 
    result = fread(content, 1, lSize, pFile); 

    rewind (pFile); 

    if (result != lSize) 
    { 
     printf("ERROR_SIZE"); 
     getchar(); 
     return ERROR_OPEN_FILE; 
    } 
    printf("SIZE_OK\n"); 

    // terminate 
    fclose(pFile); 
    printf("FILE_CLOSE\n"); 
    //allocate memory to contain the whole file + HEADER 
    buffer = (char*)malloc(sizeof(char)*lSize + 2048); 

    //print header 
    sprintf(buffer, "%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n", boundary, nameForm, filename); 
    sprintf(buffer, "%sContent-Type: %s\r\n", buffer, type); 
    //sprintf(buffer, "%sContent-Length: %d\r\n", buffer, lSize); 
    sprintf(buffer, "%s\r\n%s\r\n", buffer, content); 

    /** 
    sprintf(buffer, "%s\r\n", buffer); 
    memcpy(buffer + strlen(buffer),content,lSize); 
    sprintf(buffer, "%s\r\n", buffer); 
    */ 
    sprintf(buffer, "%s%s--\r\n", buffer, boundary); 

    //Open internet connection 
    HINTERNET hSession = InternetOpen("WINDOWS", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); 
    if (hSession == NULL) 
    { 
     printf("ERROR_INTERNET_OPEN"); 
     getchar(); 
     return ERROR_OPEN_FILE; 
    } 
    printf("INTERNET_OPENED\n"); 

    HINTERNET hConnect = InternetConnect(hSession, iaddr, INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1); 
    if (hConnect == NULL) 
    { 
     printf("ERROR_INTERNET_CONN"); 
     getchar(); 
     return ERROR_INTERNET_CONN; 
    } 
    printf("INTERNET_CONNECTED\n"); 

    HINTERNET hRequest = HttpOpenRequest(hConnect, (const char*)"POST", _T(url), NULL, NULL, NULL, INTERNET_FLAG_RELOAD, 1); 
    if (hRequest == NULL) 
    { 
     printf("ERROR_INTERNET_REQ"); 
     getchar(); 

    } 
    printf("INTERNET_REQ_OPEN\n"); 

    BOOL sent = HttpSendRequest(hRequest, hdrs, strlen(hdrs), buffer, strlen(buffer)); 

    if (!sent) 
    { 
     printf("ERROR_INTERNET_SEND"); 
     getchar(); 
     return ERROR_INTERNET_CONN; 
    } 
    printf("INTERNET_SEND_OK\n"); 
    printf("\r\n%s\r\n",buffer); 

    //close any valid internet-handles 
    InternetCloseHandle(hSession); 
    InternetCloseHandle(hConnect); 
    InternetCloseHandle(hRequest); 
} 

輸出:

OPEN_FILE 
MEMORY_ALLOCATED  "44358" 
SIZE_OK 
FILE_CLOSE 
INTERNET_OPENED 
INTERNET_CONNECTED 
INTERNET_REQ_OPEN 
INTERNET_SEND_OK 


-----------------------------7d82751e2bc0858 

Content-Disposition: form-data; name="uploadedfile"; filename="test.jpg" 

Content-Type: text/jpeg 



ÿØÿà 

-----------------------------7d82751e2bc0858-- 

感謝

+0

任何不使用libcurl或類似的理由? – deviantfan

+1

你正在打印內容,就好像它是一個字符串,這意味着它將停止在第一個0. – jsantander

+0

另外,你總是在同一個地方衝刺......你需要提前緩衝指針 – jsantander

回答

1

如果你把二進制路線

//allocate memory to contain the whole file + HEADER 
buffer = (char*)malloc(sizeof(char)*lSize + 2048); 
int chars=0; 

//print header 
chars+=sprintf(buffer+chars, "%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n", boundary, nameForm, filename); 
chars+=sprintf(buffer+chars, "Content-Type: %s\r\n", type); 
chars+=sprintf(buffer+chars, "Content-Length: %d\r\n", lSize); 

chars+=sprintf(buffer+chars, "\r\n"); 
memcpy(buffer + chars,content,lSize); 
chars+=lSize; 
chars+=sprintf(buffer+chars, "\r\n"); 

chars+=sprintf(buffer+chars, "%s--\r\n", boundary); 

但在任何情況下,我的建議是你看任何存在的許多圖書館的實現HTTP通信(libCURL是一個良好的開端)

一些其他注意事項:

代替

BOOL sent = HttpSendRequest(hRequest, hdrs, strlen(hdrs), buffer, strlen(buffer)); 

BOOL sent = HttpSendRequest(hRequest, hdrs, strlen(hdrs), buffer, chars); 

爲strlen的(緩衝區)將停止在第一個空字符處。

當您將結果打印出來時,它將被視爲字符串....並以第一個null結尾。

+0

嗨,我試過你的代碼,但它打印二進制文件。 '----------------------------- 7d82751e2bc0858 Content-Disposition:form-data; NAME = 「UploadedFile的」;文件名=「測試。JPG」 內容類型:text/JPEG 的Content-Length:44358 ÿØÿà ÿØÿà」 –

+0

對不起......我被切割和粘貼您的版本,並取消註釋部分的memcopy ......但忘了刪除一個sprintf ....現在檢查它? – jsantander

+0

它不打印結束邊界緩衝區。圖像二進制也是相同的值ÿØÿà。它不讀取完整文件 –