无法通过套接字HTTP请求获取图像数据

时间:2017-11-02 00:44:16

标签: c sockets http get request

每当我想要获得图像时,我得到的只是一些角色(4)。我想使用此命令保存图像./client example.com/image.jpg> img.jpg 我认为最后的recv存在问题。

    sprintf(request, "%s %s %s%s%s%s", "GET", path, "HTTP/1.1\r\n", 
                                        "HOST:", hostname, "\r\n\r\n");

    //Send some data with TCP
    if(send(sockfd, request, strlen(request), 0) < 0) {
        printf("Send failed\n");
        exit(1);
    }


   // printf("Request sended\n");

    if(recv(sockfd, server_reply , sizeof(server_reply), 0) < 0) {//receive answer
        printf("recv failed\n");
    }

    char *data = strstr(server_reply, "\r\n\r\n");//save data after header
    data+=4;

    //printf("Server reply: \n");//print the answer
    puts(data);

    close(sockfd);

    return 0;
}

我认为我无法接收所有图像二进制数据,但我不知道如何正确地获取所有内容。

1 个答案:

答案 0 :(得分:0)

您的代码有几个问题:

  • 您希望单个send发送所有数据。
    send可能只发送部分数据,您必须检查返回值以查看已发送的数据量和如有必要,请再次拨打电话。
  • 您希望单个recv返回完整回复。
    但是recv只会返回一次可以获得的数据,而且只返回给定的大小。如果只有少数数据,那么您需要多个recv才能获取所有数据。在localhost和LAN上交换数据时,每个recv返回的数量也会有所不同。
  • 您希望在响应完成后立即关闭TCP连接。
    但由于您使用HTTP/1.1(而不是HTTP/1.0)并且未指定明确Connection: close服务器可能会保持连接处于打开状态以等待更多请求。这意味着您的上一个recv可能会挂起。
  • 你希望图像在HTTP标题之后是一个整体。
    但是因为你使用HTTP/1.1而不是HTTP/1.0,你必须处理分块响应,即身体交付每件都以大小为前缀的碎片。

因此,我建议研究sendrecv实际做什么。此外,通过仅查看HTTP流量的一些痕迹或仅仅是示例,您不会获得实际标准的复杂性。如果您想保持简单,请使用HTTP/1.0而不是HTTP/1.1