使用post [无法上传]在C 中发送文件
Send file using POST [ Unable to upload ] in C++
我在将文件发送到服务器上很难。我已经检查了一些其他问题来解决大多数问题,但最后我无法上传文件这是我的C 代码:
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <wininet.h>
#include <iostream>
#include <tchar.h>
#pragma warning(disable : 4996)
#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 std;
int main()
{
// Local variables
static char *filename = "perf.txt"; //Filename to be loaded
static char *filepath = "C:\perf.txt"; //Filename to be loaded
static char *type = "text/plain";
static char boundary[] = "BOUNDARY"; //Header boundary
static char nameForm[] = "file"; //Input form name
static char iaddr[] = "2e8cd930.ngrok.io"; //IP address
static char url[] = "/post/upload.php"; //URL
char hdrs[512] = { '-' }; //Headers
char * buffer; //Buffer containing file + headers
char * content; //Buffer containing file
FILE * pFile; //File pointer
long lSize; //File size
size_t result;
// Open file
pFile = fopen(filepath, "rb");
if (pFile == NULL)
{
printf("ERROR_OPEN_FILE");
getchar();
return ERROR_OPEN_FILE;
}
printf("OPEN_FILEn");
// 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 + 1));
if (content == NULL)
{
printf("ERROR_MEMORY");
getchar();
return ERROR_OPEN_FILE;
}
printf("MEMORY_ALLOCATEDt "%d" n", &lSize);
// copy the file into the buffer:
result = fread(content, 1, lSize, pFile);
if (result != lSize)
{
printf("ERROR_SIZE");
getchar();
return ERROR_OPEN_FILE;
}
printf("SIZE_OKn");
content[lSize] = ' ';
// terminate
fclose(pFile);
printf("FILE_CLOSEn");
//allocate memory to contain the whole file + HEADER
buffer = (char*)malloc(sizeof(char)*lSize + 2048);
//print header
sprintf(hdrs, "Content-Type: multipart/form-data; boundary=%s", boundary);
sprintf(buffer, "-%srnContent-Disposition: form-data; name="%s"; filename="%s"rn", boundary, nameForm, filename);
sprintf(buffer, "%sContent-Type: %srn", buffer, type);
sprintf(buffer, "%srnrn%s", buffer, content);
sprintf(buffer, "%srn-%s-rn", buffer, boundary);
printf("%s", buffer);
//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_OPENEDn");
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_CONNECTEDn");
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_OPENn");
BOOL sent = HttpSendRequest(hRequest, hdrs, strlen(hdrs), buffer, strlen(buffer));
if (!sent)
{
printf("ERROR_INTERNET_SEND");
getchar();
return ERROR_INTERNET_CONN;
}
printf("INTERNET_SEND_OKn");
InternetCloseHandle(hSession);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);
getchar();
return 0;
}
这是我的php代码[upload.php],我已经更改了上传文件夹权限以创建和删除文件:
<?php
$uploaddir = 'upload/';
if (is_uploaded_file(isset($_FILES['file']['tmp_name'])?($_FILES['file'['tmp_name']]):0))
{
$uploadfile = $uploaddir . basename($_FILES['file']['name']);
echo "File ". $_FILES['file']['name'] ." uploaded successfully. ";
if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile))
{
echo "File was moved! ";
}
else
{
print_r($_FILES);
}
}
else
{
print_r($_FILES);
}
?>
使用Wireshark我的帖子请求和响应是[我已经尝试用内容-Type行以1行替换两条新行,但没有帮助更改定界符后:
POST /post/upload.php HTTP/1.1
Content-Type: multipart/form-data; boundary=BOUNDARY
User-Agent: WINDOWS
Host: 2e8cd930.ngrok.io
Content-Length: 130
Cache-Control: no-cache
-BOUNDARY
Content-Disposition: form-data; name="file"; filename="perf.txt"
Content-Type: text/plain
Whats Up?
-BOUNDARY-
HTTP/1.1 200 OK
Date: Sat, 25 Nov 2017 11:25:16 GMT
Server: Apache/2.4.27 (Debian)
Content-Length: 10
Content-Type: text/html; charset=UTF-8
Array
(
)
我不知道为什么我的服务器回复Array()。该文件没有上传。
我可以看到的第一个问题:
您在标题中说,定界符是—BOUNDARY
,然后使用与实际定界符相同的字符串。这是错误的。格式是
—DELIMITER
content
—DELIMITER
content
—DELIMITER—
,因此您的标题应该只说BOUNDARY
作为定界符。
Content-Type: multipart/form-data; boundary=BOUNDARY
您还需要将尾随的—
添加到关闭定界符。
将标头与身体分开时也有rnn
。应该是rnrn
。
这些错误将导致MIME解析器在任何地方都找不到任何形式的数据。
在性能方面,您不应使用sprintf
首先将缓冲区放置,然后将其附加到您想要附加的内容来附加数据。这会导致已经存在的复制数据过多。您应该使用strncat
,而不是因为所有内容都是要附加的字符串。或监视字符串长度,然后使用sprintf
到达结尾。有关更多信息,请参见此问题。
相关文章:
- .cpp和.h文件中的模板专用化声明
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 文本文件中的单词链表
- CMake-按正确顺序将项目与C运行时对象文件链接
- 使用新行和不使用新行读取文件
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 挂起和取消挂起一个文件DLL
- 如何确定我已使用非编码文件到达 EOF?
- 命名空间中具有.h和.cpp文件的类
- 如何使用ndk-build.cmd构建Android.so文件
- 如何使用curlpp通过POST方法上传文件和json数据
- cpp libcurl 在 HTTP post 调用中发送 zip 文件,而不使用 multipart\form-da
- 使用post [无法上传]在C 中发送文件
- 使用 POST 发送使用 C++ 的文件
- 什么fstream写函数写到文件(编码在post)
- c++ CURL post文件然后得到响应错误
- 在c++应用程序中使用libcurl从. ini文件中的值发送POST数据
- c++ | Winsock -写HTTP Post上传文件的正确方法
- 如何在c++中通过post方法发送数据到php文件
- http post-tinyxml vc++的xml文件大小