Can';无法通过套接字HTTP请求获取图像数据
每次我想拍一张照片的时候,我得到的只是一些角色。我想用这个命令保存一个图像。/client example.com/image.jpg>img.jpg 我想最后的recv有点问题Can';无法通过套接字HTTP请求获取图像数据,c,sockets,http,get,request,C,Sockets,Http,Get,Request,每次我想拍一张照片的时候,我得到的只是一些角色。我想用这个命令保存一个图像。/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 da
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;
}
sprintf(请求,“%s%s%s%s%s”,“获取”,路径,“HTTP/1.1\r\n”,
主机:,主机名,“\r\n\r\n”);
//用TCP发送一些数据
if(发送(sockfd,请求,strlen(请求),0)<0){
printf(“发送失败\n”);
出口(1);
}
//printf(“已发送的请求”);
if(recv(sockfd,server_reply,sizeof(server_reply),0)<0){//接收应答
printf(“recv失败\n”);
}
char*data=strstrstr(服务器\u回复,“\r\n\r\n”)//在标题后保存数据
数据+=4;
//printf(“服务器回复:\n”)//打印答案
(数据);
关闭(sockfd);
返回0;
}
我认为我不能接收所有的图像二进制数据,但我不知道如何正确获取所有数据 您的代码有几处错误:
- 您希望通过一次
发送所有数据。send
但是
可能只发送部分数据,您必须检查返回值以查看发送了多少数据,如有必要,请再次调用sendsend
- 您希望单个
返回完整响应recv
但是
将只返回它一次可以获得的数据量,并且只返回给定大小的数据。如果数据不止几个,则很可能需要多个recv
来获取所有数据。在本地主机和LAN上交换数据时,每个recv
返回的数据量也可能不同recv
- 您希望TCP连接在响应完成时立即关闭。
但是,由于您使用的是
(而不是HTTP/1.1
),并且没有指定明确的HTTP/1.0
,服务器可能会保持连接打开以等待更多请求。这意味着您最后的连接:close
可能会挂起recv
- 您希望图像在HTTP头之后是一个整体。
但是,由于您使用的是
而不是HTTP/1.1
,因此您也必须处理分块响应,即分块交付的主体,其中每个部分都以大小作为前缀HTTP/1.0
因此,我建议研究
send
和recv
的实际功能。此外,仅通过查看一些HTTP流量跟踪或简单的示例,您无法了解实际标准的复杂性。如果您想保持它的简单,请使用HTTP/1.0
而不是HTTP/1.1
您的代码有几处错误:
- 您希望通过一次
发送所有数据。send
但是
可能只发送部分数据,您必须检查返回值以查看发送了多少数据,如有必要,请再次调用sendsend
- 您希望单个
返回完整响应recv
但是
将只返回它一次可以获得的数据量,并且只返回给定大小的数据。如果数据不止几个,则很可能需要多个recv
来获取所有数据。在本地主机和LAN上交换数据时,每个recv
返回的数据量也可能不同recv
- 您希望TCP连接在响应完成时立即关闭。
但是,由于您使用的是
(而不是HTTP/1.1
),并且没有指定明确的HTTP/1.0
,服务器可能会保持连接打开以等待更多请求。这意味着您最后的连接:close
可能会挂起recv
- 您希望图像在HTTP头之后是一个整体。
但是,由于您使用的是
而不是HTTP/1.1
,因此您也必须处理分块响应,即分块交付的主体,其中每个部分都以大小作为前缀HTTP/1.0
因此,我建议研究
send
和recv
的实际功能。此外,仅通过查看一些HTTP流量跟踪或简单的示例,您无法了解实际标准的复杂性。如果您想保持它的简单,请使用HTTP/1.0
而不是HTTP/1.1
很多事情都可能出错,但如果recv
调用返回的数据没有预期的那么多,则需要在循环中运行它,直到获得所有数据。此外,不要期望recv
返回'\0'
终止的字符串。尤其是图像是二进制数据,因此无论在任何情况下,put
都不是打印图像的好方法。相关:@jxh是正确的。。。他正确引用的链接告诉您,响应标题将告诉您如何读取响应的内容体。此外,如果您确实收到一个“图像”,您将无法使用“put()”来输出它,因为“put()用于输出”字符串“,而不是二进制数据。很多事情都可能出错,但是如果recv
调用返回的数据没有预期的那么多,则需要在循环中运行它,直到获得所有数据为止。此外,不要期望recv
返回'\0'
终止的字符串。尤其是图像是二进制数据,因此无论在任何情况下,put
都不是打印图像的好方法。相关:@jxh是正确的。。。他正确引用的链接告诉您,响应标题将告诉您如何读取响应的内容体。此外,如果您确实收到“图像”,您将无法使用“put()”来输出它,因为“put()用于输出“字符串”,而不是二进制数据。