2009-12-31 2 views
2

Я хочу загрузить «C: \ test.txt» на веб-сервер, когда я запускаю программу, файл не загружается, и я не получаю никаких ошибок.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

+0

нет Я не установил его – student

+0

Когда я отредактировал исходный код, я получил ошибку «Ошибка: HttpSendRequest 12005», см. Выше гиперссылку – student

ответ

5

Я был в состоянии чтобы ваш код работал.

Прежде всего кода по ссылке вы предоставили, и код, который вы публикуемую не то же самое:

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

Вы должны передать имя хоста или IP-адрес здесь так «локальный» это хорошо, но "http://student114.110mb.com «нет». Если вы передадите URL-адрес, вы получите код ошибки 12005 [see WinINet error codes on msdn].

Другой проблемой является строка frmdata. Вы должны удвоить обратную косую черту в C: \ test.txt или получить символ табуляции \ t в своей строке. \ N до и после разделителей также следует заменить на \ r \ n, поскольку RFC 1521 и большинство других интернет-протоколов используют 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» обычно соответствует имени тега < input type = «file» > в HTML, но в вашем случае он указан в параметре name = строки frmdata [].

Вот PHP код, который я использовал, чтобы проверить это

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

При работе на сложном взаимодействии клиент/сервер, как это помогает проверить каждую часть отдельно. Вы могли бы, например.

  • Написать простую форму HTML загрузить на проверить ваш PHP скрипт

  • Есть программа отправить свой запрос на Netcat и изучить вывод

2

вы должны отправить полный запрос без WinAPI, если вы хотите получить хороший запрос на загрузку файла по скрипту php.

В прошлом я также пытался отправить такой запрос, как вы, со всеми функциями api. Но когда я обнюхал его с помощью wirehark, у меня было такое же решение, как и вы: заголовок слит, и он не работает.

Так что я снова использовал 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, но я не нашел ничего для моих целей.

Patrone

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";