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



每次我想要获得图像时,我得到的都是一些字符(4)。我想用这个命令保存一个图像/客户端example.com/image.jpg>img.jpg我认为结尾的recv有点问题。

sprintf(request, "%s %s %s%s%s%s", "GET", path, "HTTP/1.1rn", 
"HOST:", hostname, "rnrn");
//Send some data with TCP
if(send(sockfd, request, strlen(request), 0) < 0) {
printf("Send failedn");
exit(1);
}

// printf("Request sendedn");
if(recv(sockfd, server_reply , sizeof(server_reply), 0) < 0) {//receive answer
printf("recv failedn");
}
char *data = strstr(server_reply, "rnrn");//save data after header
data+=4;
//printf("Server reply: n");//print the answer
puts(data);
close(sockfd);
return 0;
}

我想我不能接收所有的图像二进制数据,但我不知道如何正确地获取所有数据。

您的代码有几个问题:

  • 您期望单个send发送所有数据
    但是send可能只发送部分数据,您必须检查返回值以查看发送了多少数据,如果需要,请再次调用send
  • 您期望单个recv返回完整响应
    但是recv一次只能返回它能得到的数据,并且只能返回给定大小的数据。如果数据不止几个,则需要多个recv才能获得所有数据的可能性很高。在本地主机和局域网上交换数据时,每个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

最新更新