2009-12-31 64 views
2

我想上傳「C:\ test.txt」到網絡服務器,當我運行程序時,文件沒有上傳,我沒有收到任何錯誤。在Web服務器Dev C++ Wininet上傳文件使用HTTP

the complete C++ code can be find here

和PHP代碼可以在這裏找到: 「http://student114.110mb.com/upload.txt」 或 「http://student114.110mb.com/upload.php

好心幫我哪裏做錯了

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

#pragma comment(lib,"wininet.lib") 

using namespace std; 

int main() 
{ 

    static TCHAR frmdata[] = "-----------------------------7d82751e2bc0858\nContent-Disposition: form-data; name=\"uploadedfile\"; filename=\"C:\test.txt\"\nContent-Type: text/plain\n\nfile contents here\n-----------------------------7d82751e2bc0858--"; 
    static TCHAR hdrs[] = "Content-Type: multipart/form-data; boundary=---------------------------7d82751e2bc0858"; 

    HINTERNET hSession = InternetOpen("MyAgent",INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); 
    if(hSession==NULL) 
    { 
    cout<<"Error: InternetOpen"; 
    } 


    HINTERNET hConnect = InternetConnect(hSession, _T("localhost"),INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1); 
    if(hConnect==NULL) 
    { 
    cout<<"Error: InternetConnect"; 
    } 

    HINTERNET hRequest = HttpOpenRequest(hConnect, (const char*)"POST",_T("upload.php"), NULL, NULL, (const char**)"*/*\0", 0, 1); 
    if(hRequest==NULL) 
    { 
    cout<<"Error: HttpOpenRequest"; 
    } 

    BOOL sent= HttpSendRequest(hRequest, hdrs, strlen(hdrs), frmdata, strlen(frmdata)); 
    if(!sent) 
    { 
    cout<<"Error: HttpSendRequest"; 
    } 

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

    return 0; 
} 
+0

您是否安裝小提琴手,看到正在發送的HTTP流量?我會先從那裏開始。 – Alan 2009-12-31 13:29:42

+0

不,我沒有安裝它 – student 2009-12-31 13:37:58

+0

當我編輯源代碼,然後我得到錯誤「錯誤:HttpSendRequest 12005」,見上面的超鏈接 – student 2009-12-31 13:46:27

回答

5

我能使您的代碼工作。

你提供的鏈接,你發佈的代碼上的所有代碼首先是不一樣的:

InternetConnect(hSession, _T("localhost"), ... 
InternetConnect(hSession, _T("http://student114.110mb.com"), ... 

你必須在這裏傳遞一個主機名或IP地址,以便「localhost」的是好的,但「http://student114.110mb.com 「不是。 如果你傳遞一個URL,你將得到12005錯誤代碼[see WinINet error codes on msdn]

另一個問題是frmdata字符串。你應該在C:\ test.txt中加一個反斜槓,否則你的字符串中會出現一個製表符。 \ n之前和之後的分隔符也應該被替換爲\ r \ n,因爲RFC 1521和大多數其他Internet協議使用CRLF作爲行分隔符。

這是我用過的字符串。

static TCHAR frmdata[] = "-----------------------------7d82751e2bc0858\r\nContent-Disposition: form-data; name=\"uploadedfile\"; filename=\"C:\\test.txt\"\r\nContent-Type: text/plain\r\n\r\nfile contents here\r\n-----------------------------7d82751e2bc0858--\r\n"; 

最後的PHP代碼不起作用,因爲您使用$ _FILES [ 「文件」],你應該使用$ _FILES [ 「UploadedFile的」。 「uploadedfile」通常對應於HTML中的< input type =「file」>標籤的名稱,但在您的情況下,它在frmdata []字符串的name =參數中指定。

這裏是我曾經用來測試這個

move_uploaded_file($_FILES["uploadedfile"]["tmp_name"], "/files/my_file"); 

當你在這樣複雜的客戶端/服務器交互工作,它有助於分別測試每個部分的PHP代碼。你可以舉例。

  • 編寫一個簡單的HTML上傳表單 測試你的PHP腳本

  • 讓你的程序發送的請求 的netcat並檢查輸出

2

你必須發送一個完整的請求沒有WinAPI如果你想有一個很好的請求通過PHP腳本上傳文件。

在過去,我也嘗試發送像你這樣的請求,所有的API函數。 但是,當我用wireshark嗅探它時,我得到了和你一樣的解決方案:標題被合併,並且不起作用。

所以我再次使用了winsock,如果你想發送的數據不是太大,它就會工作。

下面的代碼:

#include <iostream> 
#include <winsock2.h> 
#include <string> 
using namespace std; 

//link libwsock32.a 

unsigned long WinsockStart() 
{ 
    WSADATA wsa; 
    unsigned long ulong; 
    struct hostent *host; 

    if(WSAStartup(MAKEWORD(2,2), &wsa) < 0) 
    { 
      cout << "Error WinsockStart()" << endl; 
      WSACleanup(); 
      return 1; 
      } 

    if((host=gethostbyname("www.example.com"))<0) 
    { 
      cout << "Fehler gethostbyname()" << endl; 
      WSACleanup(); 
      return 2; 
      } 

    ulong = *(unsigned long*) host->h_addr; 

    return ulong; 
     } 

    void error_exit(string text) 
    { 
    cout << text; 
    WSACleanup(); 
    exit(EXIT_FAILURE); 
     } 



int main() 
{ 
SOCKET sock; 
struct sockaddr_in addr; 
unsigned long win=0; 
int con = 0, gr=0, send_r=0, rec=0; 
char header[2048], puffer[2018]; 
string to_send="hello world"; 
string name="test99.txt"; 

win=WinsockStart(); 
    if(win==1||win==2) 
     error_exit("Error WinsockStart()"); 

addr.sin_family=AF_INET; 
addr.sin_port=htons(80); 
addr.sin_addr.s_addr = win; 

sock = socket(AF_INET, SOCK_STREAM, 0); 
    if(sock<0) 
     error_exit("Error socket()"); 

gr = (to_send.size()+name.size()+287); 

sprintf(header, "POST /upload.php HTTP/1.1\r\n"); 
sprintf(header, "%sHost: www.example.com\r\n", header); 
sprintf(header, "%sConnection: Keep-Alive\r\n", header); 
sprintf(header, "%sContent-Type: multipart/form-data; boundary=---------------------------90721038027008\r\n", header); 
sprintf(header, "%sContent-Length: %d\r\n", header, gr); 
sprintf(header, "%s\r\n", header); 
sprintf(header, "%s-----------------------------90721038027008\r\n", header); 
sprintf(header, "%sContent-Disposition: form-data; name=\"upfile\"; filename=\"%s\"\r\n", header, name.c_str()); 
sprintf(header, "%sContent-Type: text/plain\r\n", header); 
sprintf(header, "%s\r\n", header); 
sprintf(header, "%s%s\r\n", header, to_send.c_str()); 
sprintf(header, "%s-----------------------------90721038027008\r\n", header); 
sprintf(header, "%sContent-Disposition: form-data; name=\"post\"\r\n", header); 
sprintf(header, "%s\r\n", header); 
sprintf(header, "%supload\r\n\r\n", header); 
sprintf(header, "%s-----------------------------90721038027008--\r\n\r\n\0", header);  

con = connect(sock, (SOCKADDR*)&addr, sizeof(addr)); 
    if(con < 0) 
     error_exit("Error connect()"); 

if(send_r=send(sock, header, strlen(header), 0)<0) 
     error_exit("Error send()"); 

while(rec=recv(sock, puffer, 2048, 0)) 
{ 
    if(rec==0) 
    error_exit("Server quit"); 

printf("%s", puffer); 
}    

closesocket(sock); 
WSACleanup(); 
return EXIT_SUCCESS; 
} 

到現在爲止,我已經搜查,我已經嘗試使用WinHttpAPI其他解決方案,但我沒有找到我的目的什麼。

帕特龍

P.S.對不起,我的英語不好,這不是我的母語

1
static TCHAR frmdata[] = "-----------------------------7d82751e2bc0858\r\nContent-Disposition: form-data; name=\"uploadedfile\"; filename=\"C:\\test.txt\"\r\nContent-Type: text/plain\r\n\r\nfile contents here\r\n-----------------------------7d82751e2bc0858--\r\n"; 

末「 - 」字應該是之前的「--------------------- -------- 7d82751e2bc0858「的邊界,不在之後。

正確的代碼:

static TCHAR frmdata[] = "-----------------------------7d82751e2bc0858\r\nContent-Disposition: form-data; name=\"uploadedfile\"; filename=\"C:\\test.txt\"\r\nContent-Type: text/plain\r\n\r\nfile contents here\r\n-------------------------------7d82751e2bc0858\r\n";