每次我想获取图像时,我得到的只是一些字符 (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 都以大小为前缀。
因此,我建议研究一下 send
和 recv
的实际作用。此外,仅通过查看 HTTP 流量的一些痕迹或简单的示例,您不会了解实际标准的复杂性。如果您想保持简单,请使用 HTTP/1.0
而不是 HTTP/1.1
。
关于无法通过socket HTTP请求获取图片数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47065832/