c++通过HTTP发送图像
C++ Sending Image via HTTP
我尝试用c++实现一个简单的HTTP服务器。我可以向浏览器发送文本响应,但是我无法为二进制文件请求发送响应。
下面是我的代码,以获得HTML响应的PNG文件请求:
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 -> %sn", file_name);
}
string html = "HTTP/1.1 200 OkayrnContent-Type: text/html; charset=ISO-8859-4 rnrn" + 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 OkayrnContent-Type: image/png; Content-Transfer-Encoding: binary; Content-Length: " + file_size_str + ";charset=ISO-8859-4 rnrn" + file_str;
printf("nnHTML -> %snnfile_str -> %ldnnn", html.c_str(), file_str.length());
}
return html;
}
这段代码成功地在char* buffer
上读取文件并存储数据。让我困惑的是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 -> %ldn", mystring.c_str(), mystring.length());
fclose(file_stream );
}
但是HTML输出总是相同的,并且mystring
在打印时也只包含211PNG
。
我走错路了吗?请帮忙找出我代码中的错误。谢谢你。
您将数据存储在一个std::stringstream
中的大块中。这将不起作用,因为值0将被解释为空终止符。这将导致忽略空终止符之后的所有内容。你应该使用像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 );
为了使上面的工作,您需要重新打开stdout
,使其以二进制模式写入。这个答案在Stackoverflow上展示了如何做到这一点。这只是为了将内容输出到stdout
,因为您通过套接字传输日期,因此不必对stdout
做任何操作。
首先,您需要打开文件(您的图片所在的位置)来读取二进制文件。
fp=fopen(filename,"rb");
接下来,使用以下命令将stdout设置为二进制模式:
_setmode(_fileno(stdout),O_BINARY);
您需要包含<fcntl.h> and <io.h>
标头。找出这幅画的确切尺寸你需要发送,例如像Captain Obvilous写的:
fseek(fp, 0L, SEEK_END);
long file_length = ftell(fp);
rewind(fp);
现在使用fread函数从图片中读取所有字节:
while (!feof(fp))
{
fread(&ch, 1, 1, fp);
cout << ch;
}
变量ch是char类型。当你完成设置文件模式:
_setmode(_fileno(stdout), _O_TEXT);
**注意:**这段代码主要是用C编写的,但你可以使用istream
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- OpenCV EqualizeHist()从彩色图像创建黑白图像
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 如何在boost beast http请求中设置http头
- 平均图像时图像损坏
- 在C++中使用GDAL可以将图像的像素坐标转换为lat,long吗
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- Vulkan验证层不断在VkQueuePresentKHR()上抛出图像布局错误
- 在多个核心中处理一个HTTP请求
- 使用 cpprest 通过 json 对象在 http post 中发送图像
- libcURL POST 分段上传(带有缓冲图像)返回 HTTP 400
- C++中的图像HTTP上载已损坏
- Go http:从Qt客户端发送图像后没有这样的文件
- 如何使用Poco C++从HTTP服务器响应中读取图像内容
- c++通过HTTP发送图像
- 通过http GET请求接收JPEG图像
- cURL下载相机的图像(http请求)
- 如何通过http下载和保存图像
- 如何在c++中从URL(HTTP)中获取图像