gpt4 book ai didi

c++ - 在 C/C++ 中使用 winsocks 发送原始请求(http post 文件数据)

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:49:56 24 4
gpt4 key购买 nike

我从事一个小项目,该项目将使用 C++ 应用程序发送文件(图像)并通过 http(无 ftp)在网络服务器上接收它。

我使用 winsocks 发送查询,但我的问题是:

    std::string query=
"POST /test/upload.php HTTP/1.1\r\n"
"Host: site.net\r\n"
"User-Agent: User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36\r\n"
"Connection: Keep-alive\r\n\r\n"
"Content-Length: "+FileSize+"\r\n"
"Content-Type: multipart/form-data; boundary=----WebKitFormBoundarym9PgiUg6fjxm2Hpr\r\n"

"------WebKitFormBoundarym9PgiUg6fjxm2Hpr\r\n"
"Content-Disposition: form-data; name=\"tmp\"; filename=\"photo.jpg\"\r\n"
"Content-Type: image/jpeg\r\n\r\n"
+StrData+
"------WebKitFormBoundarym9PgiUg6fjxm2Hpr--\r\n";

我需要将我的文件的 HEX 放在这里 -> StrData 但我不知道该怎么做?...

最佳答案

不,您不需要以十六进制发送文件数据。您需要按原样发送文件的原始原始二进制数据。假设文件很小,您可以将其按原样填充到 std::string 中。

顺便说一句,您的请求格式不正确 - Connection header 中的 \r\n 太多。额外的 \r\n 属于最后一个 header 之后。并且不要将 Content-Length header 与 multipart 内容类型一起使用,因为它们会自行终止 - 特别是因为您指定了错误的值。如果要指定 Content-Length,则必须先计算完整 MIME 数据的长度,然后再创建继续它的 header 。

试试这个:

std::ifstream File("filename", std::ios::in | std::ios::binary | std:::ios::ate);
if (file)
{
std::ifstream::pos_type FileSize = File.tellp();
File.seekg(0);

std::string StrData;
if (FileSize > 0)
{
StrData.resize(FileSize);
File.read(&StrData[0], FileSize);
}

File.close();

std::string query =
"POST /test/upload.php HTTP/1.1\r\n"
"Host: site.net\r\n"
"User-Agent: User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36\r\n"
"Connection: Keep-alive\r\n"
"Content-Type: multipart/form-data; boundary=----WebKitFormBoundarym9PgiUg6fjxm2Hpr\r\n"
"\r\n"
"------WebKitFormBoundarym9PgiUg6fjxm2Hpr\r\n"
"Content-Disposition: form-data; name=\"tmp\"; filename=\"photo.jpg\"\r\n"
"Content-Type: image/jpeg\r\n"
"\r\n"
+StrData+
"\r\n"
"------WebKitFormBoundarym9PgiUg6fjxm2Hpr--\r\n";

// send query ...
}

话虽如此,最好不要尝试将整个 HTTP 请求塞入单个 std::string。首先发送初始请求 header ,然后发送原始文件数据,最后发送终止边界。例如:

std::fstream File("filename", std::ios::in | std::ios::binary);
if (file)
{
char chunk[1024];
std::streamsize chunksize;

std::string str =
"POST /test/upload.php HTTP/1.1\r\n"
"Host: site.net\r\n"
"User-Agent: User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36\r\n"
"Connection: Keep-alive\r\n"
"Content-Type: multipart/form-data; boundary=----WebKitFormBoundarym9PgiUg6fjxm2Hpr\r\n"
"\r\n"
"------WebKitFormBoundarym9PgiUg6fjxm2Hpr\r\n"
"Content-Disposition: form-data; name=\"tmp\"; filename=\"photo.jpg\"\r\n"
"Content-Type: image/jpeg\r\n"
"\r\n";

// send str ...

do
{
chunksize = File.readsome(chunk, sizeof(chunk));
if (chunksize < 1)
break;

// send chunk up to chunksize bytes ...
}
while (true);

File.close();

str =
"\r\n"
"------WebKitFormBoundarym9PgiUg6fjxm2Hpr--\r\n";

// send str ...

关于c++ - 在 C/C++ 中使用 winsocks 发送原始请求(http post 文件数据),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17524002/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com