gpt4 book ai didi

C++ 从 HTTP 响应中获取图片

转载 作者:可可西里 更新时间:2023-11-01 17:32:54 29 4
gpt4 key购买 nike

我正在尝试从网站下载图片。问题是即使我从 HTTP 响应正文中获取了所有内容,文件也无法打开。我一直在努力解决这个问题,但我找不到真正的问题。我确实注意到的一件事是,使用 chromium 下载的图片显示的字符与使用命令从我的代码下载的图片不同:$ 猫图片.png |少

#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <fstream>
#include <iostream>

using std::cout;
using std::endl;

//with this function I remove HTTP header info, so I only get content.
char *removeHTTPHeader(char *buffer) {
char *t = strstr(buffer, "\r\n\r\n");
t = t + 4;
return t;
}

void getPicture(const int &socketfd, const int &bSize) {
std::ofstream file("picture.png",
std::ofstream::binary | std::ofstream::out);

char buffer[bSize];
ssize_t bReceived;

bReceived = recv(socketfd, buffer, bSize, 0);
char *t = removeHTTPHeader(buffer);
file.write(t, strlen(t));
memset(buffer, 0, bSize);

while ((bReceived = recv(socketfd, buffer, bSize, 0)) > 0) {
file.write(buffer, bReceived);
memset(buffer, 0, bSize);
}

file.close();
}

int main() {

int status;
addrinfo host_info;
addrinfo *host_info_list;

memset(&host_info, 0, sizeof(host_info));

host_info.ai_family = AF_UNSPEC;
host_info.ai_socktype = SOCK_STREAM;
host_info.ai_protocol = 0;

status = getaddrinfo("www.pngimg.com", "80", &host_info, &host_info_list);
if (status != 0) {
cout << "getaddrinfo error" << endl;
}

int socketfd;
socketfd = socket(host_info_list->ai_family, host_info_list->ai_socktype,
host_info_list->ai_protocol);

addrinfo *rp;
for (rp = host_info_list; rp != NULL; rp = rp->ai_next) {

socketfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);

if (socketfd == -1) {
cout << "socket error" << endl;
}

if (connect(socketfd, rp->ai_addr, rp->ai_addrlen) != -1) {
break;
}
close(socketfd);
}

if (rp == NULL) {
cout << "Could not connect!" << endl;
exit(EXIT_FAILURE);
}

freeaddrinfo(host_info_list);

const char *msg =
"GET /upload/water_PNG3290.png HTTP/1.1\r\nhost: www.pngimg.com\r\nConnection: close\r\n\r\n";

status = send(socketfd, msg, strlen(msg), 0);

if (status == -1) {
cout << "error sending" << endl;
exit(EXIT_FAILURE);
}

getPicture(socketfd, 1024);
close(socketfd);

return 0;
}

这是使用 cat 命令的图片: terminal above is picture from my code, below is picture from chromium "save as"

最佳答案

问题是我不知道在 C 风格的字符串中你不能对二进制数据执行 strlen。这就是为什么我必须在函数 removeHTTPHeader 中添加计数器。以下是我更改的函数 getPicture 和 removeHTTPHeader。

char *removeHTTPHeader(char *buffer, int &bodySize) {
char *t = strstr(buffer, "\r\n\r\n");
t = t + 4;

for (auto it = buffer; it != t; ++it) {
++bodySize;
}

return t;
}

void getPicture(const int &socketfd, const int &bSize) {
std::ofstream file("picture.png",
std::ofstream::binary | std::ofstream::out);

char buffer[bSize];
ssize_t bReceived;

bReceived = recv(socketfd, buffer, bSize, 0);
int bodySize = 0;

char *t = removeHTTPHeader(buffer, bodySize);
bodySize = bReceived - bodySize;

file.write(t, bodySize);
memset(buffer, 0, bSize);

while ((bReceived = recv(socketfd, buffer, bSize, 0)) > 0) {
file.write(buffer, bReceived);
memset(buffer, 0, bSize);
}

file.close();
}

关于C++ 从 HTTP 响应中获取图片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37985610/

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