首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >获取C++图片

获取C++图片
EN

Stack Overflow用户
提问于 2016-06-23 08:05:26
回答 1查看 2.5K关注 0票数 1

我想从网站上下载照片。问题是,即使我从HTTP响应体获得所有内容,文件也不会打开。我一直在努力解决这个问题,但我找不到真正的问题。我注意到的一件事是,使用铬下载的图片显示的字符与使用命令从代码中下载的图片不同:$ cat,picture.png,less

代码语言:javascript
复制
#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命令的图片:上面的终端是我代码中的图片,下面是铬“保存为”的图片。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-23 18:02:52

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

代码语言:javascript
复制
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();
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37985610

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档