无法通过socket HTTP请求获取图片数据

标签 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;
}

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

最佳答案

您的代码有几处错误:

  • 您希望单个send 发送所有数据。
    但是send 可能只发送部分数据,您必须检查返回值才能看到发送了多少数据,如有必要请再次发送。
  • 您希望单个 recv 返回完整的响应。
    但是recv 只会返回一次可以获取的数据,并且不会超过给定的大小。如果数据不止一些,则很有可能需要多次 recv 来获取所有数据。在本地主机和 LAN 上交换数据时,每个 recv 将返回多少也可能不同。
  • 您希望 TCP 连接在响应完成后立即关闭。
    但是由于您使用的是 HTTP/1.1(而不是 HTTP/1.0 ) 并且不指定显式 Connection: close 服务器可能会保持连接打开以等待更多请求。这意味着您的最后一个 recv 可能会挂起。
  • 您希望图像在 HTTP header 之后成为一体。
    但是由于您使用的是 HTTP/1.1 而不是 HTTP/1.0,因此您必须也处理分块响应,即正文分块交付,每 block 都以大小为前缀。

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

关于无法通过socket HTTP请求获取图片数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47065832/

相关文章:

c# - 将 IPv6 环回地址解析为 Uri

java - 如何模拟客户端中止请求?

http - 在我的 Windows Phone 上获取主机文件

java - 我想将Java中的字节数据转换为C

html - 如何在 HTML 中显示原始 rgb 图像

python - 如何访问连接到heroku的socket服务器

python - wget 给出响应 ERROR : 418 unused

c - 流水线 - 在两个程序之间发送字符串

通过宏组合两个指定的初始化器

php - 在PHP中进行进程间通信的最简单方法是什么?