gpt4 book ai didi

C++ 通过 HTTP 发送图像

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:03:31 25 4
gpt4 key购买 nike

我尝试使用 C++ 实现一个简单的 HTTP 服务器。我能够向浏览器发送文本响应,但无法发送二进制文件请求的响应。

这是我获取对 PNG 文件请求的 HTML 响应的代码:

string create_html_output_for_binary(const string &full_path)
{
const char* file_name = full_path.c_str();

FILE* file_stream = fopen(file_name, "rb");

string file_str;

size_t file_size;

if(file_stream != nullptr)
{
fseek(file_stream, 0, SEEK_END);

long file_length = ftell(file_stream);

rewind(file_stream);

// Allocate memory. Info: http://www.cplusplus.com/reference/cstdio/fread/?kw=fread
char* buffer = (char*) malloc(sizeof(char) * file_length);

if(buffer != nullptr)
{
file_size = fread(buffer, 1, file_length, file_stream);

stringstream out;

for(int i = 0; i < file_size; i++)
{
out << buffer[i];
}

string copy = out.str();

file_str = copy;
}
else
{
printf("buffer is null!");
}
}
else
{
printf("file_stream is null! file name -> %s\n", file_name);
}

string html = "HTTP/1.1 200 Okay\r\nContent-Type: text/html; charset=ISO-8859-4 \r\n\r\n" + string("FILE NOT FOUND!!");

if(file_str.length() > 0)
{
// HTTP/1.0 200 OK
// Server: cchttpd/0.1.0
// Content-Type: image/gif
// Content-Transfer-Encoding: binary
// Content-Length: 41758

string file_size_str = to_string(file_str.length());

html = "HTTP/1.1 200 Okay\r\nContent-Type: image/png; Content-Transfer-Encoding: binary; Content-Length: " + file_size_str + ";charset=ISO-8859-4 \r\n\r\n" + file_str;

printf("\n\nHTML -> %s\n\nfile_str -> %ld\n\n\n", html.c_str(), file_str.length());
}

return html;
}

此代码成功读取文件并将数据存储在 char* 缓冲区。让我感到困惑的是 file_str 总是包含 \211PNG,尽管当我检查它的大小时,它比 \211PNG 大得多。我怀疑这是导致我的图像没有在浏览器中加载的问题,因为当我打印 html 时,它只显示:

HTTP/1.1 200 Okay
Content-Type: image/png; Content-Transfer-Encoding: binary; Content-Length: 187542;charset=ISO-8859-4

\211PNG

我在想的是向浏览器发送二进制数据的方式与发送文本数据的方式相同,所以我先制作字符串标题,然后读取文件数据,将其转换为字符串并与标题结合,最后发送一个大的单个字符串到 HTTP 套接字。

我也试过这个代码:

if (file_stream != NULL)
{
short stringlength = 6;

string mystring;

mystring.reserve(stringlength);

fseek(file_stream , 0, SEEK_SET);
fread(&mystring[0], sizeof(char), (size_t)stringlength, file_stream);

printf("TEST -> %s, length -> %ld\n", mystring.c_str(), mystring.length());

fclose(file_stream );
}

但是 HTML 输出总是一样的,并且 mystring 在 printf-ed 时也只包含 \211PNG

我是不是走错路了?请帮助找出我的代码中的错误。谢谢。

最佳答案

您正在将一大块数据存储到 std::stringstream 中。这将不起作用,因为零值将被解释为空终止符。这会导致空终止符之后的所有内容都被忽略。您应该使用像 std::vector 这样的容器来存储和管理二进制数据。

#include <vector>

string create_html_output_for_binary(const string &full_path)
{
std::vector<char> buffer;

//... other code here

if(ile_stream != nullptr)
{
fseek(file_stream, 0, SEEK_END);
long file_length = ftell(file_stream);
rewind(file_stream);

buffer.resize(file_length);

file_size = fread(&buffer[0], 1, file_length, file_stream);
}

// .... other code here
}

要输出数据,请使用printf。它可能会以不同的方式处理新行,并且会在遇到第一个空终止符时停止。相反(与您对 C 流 IO 的使用保持一致)使用 fwrite

fwrite (buffer.data(), 1 , buffer.size() , stdout );

为了使上述工作正常,您需要重新打开它以二进制模式写入的 stdoutThis answer在 Stackoverflow 上,这里展示了如何实现这一点。这只是将内容输出到 stdout 由于您通过套接字传输日期,因此您不必对 stdout 做任何事情。

关于C++ 通过 HTTP 发送图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16762018/

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