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

C++ C++;从HTTP响应获取图片,c++,image,sockets,http,header,C++,Image,Sockets,Http,Header,我正在尝试从网站下载图片。问题是,即使我从HTTP响应体获取所有内容,文件也不会打开。我一直试图解决这个问题,但我找不到真正的问题。我注意到,使用chromium下载的图片显示的字符与使用以下命令从我的代码下载的图片显示的字符不同: $cat picture.png |更少 #包括 #包括 #包括 #包括 #包括 #包括 #包括 使用std::cout; 使用std::endl; //通过这个函数,我删除HTTP头信息,所以我只获取内容。 char*removeHTTPHeader(char

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

#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用std::cout;
使用std::endl;
//通过这个函数,我删除HTTP头信息,所以我只获取内容。
char*removeHTTPHeader(char*buffer){
char*t=strstrstr(缓冲区,“\r\n\r\n”);
t=t+4;
返回t;
}
void getPicture(常量int和socketfd、常量int和bSize){
std::of流文件(“picture.png”,
std::ofstream::binary | std::ofstream::out);
字符缓冲区[bSize];
塞泽特·布雷塞维德;
bReceived=recv(socketfd,buffer,bSize,0);
char*t=removeHTTPHeader(缓冲区);
write(t,strlen(t));
memset(缓冲区,0,bSize);
而((bReceived=recv(socketfd,buffer,bSize,0))>0){
file.write(buffer,bReceived);
memset(缓冲区,0,bSize);
}
file.close();
}
int main(){
智力状态;
addrinfo主机信息;
addrinfo*主机信息列表;
memset(&host_info,0,sizeof(host_info));
host_info.ai_family=AF_unsec;
host_info.ai_socktype=SOCK\u流;
host_info.ai_协议=0;
status=getaddrinfo(“www.pngimg.com”、“80”和主机信息以及主机信息列表);
如果(状态!=0){
不可能是那种类型,
主机信息列表->人工智能协议);
addrinfo*rp;
对于(rp=host\u info\u list;rp!=NULL;rp=rp->ai\u next){
socketfd=socket(rp->ai_族,rp->ai_socktype,rp->ai_协议);
如果(socketfd==-1){
cout ai_addrlen)!=-1){
打破
}
关闭(socketfd);
}
如果(rp==NULL){

问题是我不知道在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();
}

您不能在二进制数据上使用
strlen
。谢谢,我更改了它。但我想这不是真正的问题。从
char*
构造
std::string
也将在数据的第一个0处停止。您很可能希望从
bReceived
中减去头中的字节数,然后编写其余的文件的缓冲区。谢谢!我照你说的做了。我把removeHTTPHeader改回了char*,并计算了正文大小。
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();
}