2009-12-31 81 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";