开发 C++ Wininet 使用 HTTP 上传文件
我想将“C:\test.txt”上传到网络服务器,当我运行程序时,文件没有上传,并且没有收到任何错误。
,网络服务器上的 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;
}
I want to upload "C:\test.txt" to webserver, when I am running program, file is not uploading and I am not getting any error.
the complete C++ code can be find here
and php code on webserver can be find here: "http://student114.110mb.com/upload.txt"
or
"http://student114.110mb.com/upload.php"
kindly help me where I am doing wrong
#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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我能够使你的代码工作。
首先,您提供的链接上的代码和您发布的代码不同:
您必须在此处传递主机名或 IP 地址,因此“localhost”很好,但“http://student114.110mb.com" 不是。
如果您传递 URL,您将收到 12005 错误代码 [请参阅 msdn 上的 WinINet 错误代码]。
另一个问题是 frmdata 字符串。您应该在 C:\test.txt 中加倍反斜杠,否则您的字符串中将出现一个制表符 \t。分隔符前后的 \n 也应替换为 \r\n,因为 RFC 1521 和大多数其他 Internet 协议使用 CRLF 作为行分隔符。
这是我使用过的字符串。
最后,PHP 代码不起作用,因为您在应该使用 $_FILES["uploadedfile"] 的地方使用了 $_FILES["file"]。 “uploadedfile”通常对应于文件的名称。 HTML 中的标记,但在您的情况下,它是在 frmdata[] 字符串的 name= 参数中指定的。
这是我用来测试这个的 PHP 代码。
当您处理像这样复杂的客户端/服务器交互时,它有助于单独测试每个部分。例如,你可以。
编写一个简单的 HTML 上传表单
测试您的 php 脚本
让您的程序将其请求发送到
netcat 并检查输出
I was able to make your code work.
First of all the code on the link you provided and the code you posted is not the same:
You must pass an host name or ip address here so "localhost" is good but "http://student114.110mb.com" isn't.
If you pass an URL you will get the 12005 error code [see WinINet error codes on msdn].
Another problem is the frmdata string. You should double the backslash in C:\test.txt or you will get a tab character \t in your string. The \n before and after the delimiters should also be replaced by \r\n because RFC 1521 and most other internet protocols use CRLF as a line delimiter.
Here is the string I have used.
Finally the PHP code doesn't work because you use $_FILES["file"] where you should be using $_FILES["uploadedfile"]. "uploadedfile" would typically correspond to the name of an <input type="file"> tag in HTML but in your case it is specified in the name= parameter of the frmdata[] string.
Here's the PHP code I have used to test this
When you work on complex client/server interaction like this it helps to test each part separately. You could for instance.
Write a simple HTML upload form to
test your php script
Have your program send its request to
netcat and examine the output
如果您想通过 php 脚本上传文件的良好请求,则必须发送不带 WinAPI 的完整请求。
过去,我也尝试过像你一样发送这样的请求,以及所有的api函数。
但是当我用wireshark嗅探它时,我得到了和你一样的解决方案:标头被合并,但它不起作用。
所以我再次使用了winsock,如果你要发送的数据不太大,它就可以工作。
代码如下:
到目前为止,我已经搜索并尝试了使用 WinHttpAPI 的其他解决方案,但没有找到任何适合我目的的解决方案。
赞助
人抱歉我的英语不好,这不是我的母语
you have to send a full request without the WinAPI if you want to have a good request for uploading a file over a php script.
In the past, I also tried to send such a request like you, with all the api functions.
But when I sniffed it with wireshark, I got the same solution like you: the header is merged and it didn't work.
So I used winsock again and it worked if the data which you want to send aren't too big.
here's the code:
Until now, I've searched and I've tried for other solutions using the WinHttpAPI, but I didn't find anything for my purposes.
Patrone
P.S. Sorry for my bad english, it's not my native language
最后一个“--”字符应该位于“----------------------------7d82751e2bc0858”边界之前,而不是之后。
正确代码:
Last "--" characters should be before the "-----------------------------7d82751e2bc0858" boundary, not after it.
Correct code: