C++ 使用http get下载图片只下载图片的一小部分
我正在尝试使用http协议GET请求服务器向我发送图片。它会编译并要求提供图片,但服务器只会向我发送一小部分图片 我的代码是:C++ 使用http get下载图片只下载图片的一小部分,c++,http,winsock,C++,Http,Winsock,我正在尝试使用http协议GET请求服务器向我发送图片。它会编译并要求提供图片,但服务器只会向我发送一小部分图片 我的代码是: #include <iostream> #include <string> #include <Windows.h> #include <fstream> #include <stdlib.h> #include <winsock.h> #pragma comment(lib, "wsock32
#include <iostream>
#include <string>
#include <Windows.h>
#include <fstream>
#include <stdlib.h>
#include <winsock.h>
#pragma comment(lib, "wsock32.lib")
using namespace std;
#define BUFFERSIZE 1024
void die_with_error(char *errorMessage);
void die_with_wserror(char *errorMessage);
int main(int argc, char *argv[])
{
string request;
string response;
int resp_leng;
char buffer[BUFFERSIZE];
struct sockaddr_in serveraddr;
int sock;
WSADATA wsaData;
char *ipaddress = "210.125.167.240";
int port = 80;
//http://cwc.ghc.ac.kr/skin/base/board/view_brit2.gif
request+="GET /skin/base/board/view_brit2.gif HTTP/1.0\r\n";
request+="Host: cwc.ghc.ac.kr\r\n";
request+="\r\n";
//init winsock
if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)
die_with_wserror("WSAStartup() failed");
//open socket
if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
die_with_wserror("socket() failed");
//connect
memset(&serveraddr, 0, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr(ipaddress);
serveraddr.sin_port = htons((unsigned short) port);
if (connect(sock, (struct sockaddr *) &serveraddr, sizeof(serveraddr)) < 0)
die_with_wserror("connect() failed");
//send request
if (send(sock, request.c_str(), request.length(), 0) != request.length())
die_with_wserror("send() sent a different number of bytes than expected");
//get response
response = "";
resp_leng= BUFFERSIZE;
while (resp_leng == BUFFERSIZE)
{
resp_leng= recv(sock, (char*)&buffer, BUFFERSIZE, 0);
if (resp_leng>0)
response+= string(buffer).substr(0,resp_leng);
}
ofstream myfile;
myfile.open ("C:\\a\\example.gif");
//display response
cout << response << endl;
//get response
response = "";
resp_leng= BUFFERSIZE;
while (resp_leng == BUFFERSIZE)
{
resp_leng= recv(sock, (char*)&buffer, BUFFERSIZE, 0);
if (resp_leng>0)
response+= string(buffer).substr(0,resp_leng);
}
//display response
cout << response << endl;
myfile << response;
myfile.close();
//disconnect
closesocket(sock);
//cleanup
WSACleanup();
return 0;
}
void die_with_error(char *errorMessage)
{
cerr << errorMessage << endl;
exit(1);
}
void die_with_wserror(char *errorMessage)
{
cerr << errorMessage << ": " << WSAGetLastError() << endl;
exit(1);
}
/*
It compiles and runs fine the output is:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
ETag: W/"60-1144808550000"
Last-Modified: Wed, 12 Apr 2006 02:22:30 GMT
Content-Type: image/gif
Content-Length: 60
Date: Wed, 22 Feb 2012 04:29:04 GMT
Connection: close
GIF89a
*/
#包括
#包括
#包括
#包括
#包括
#包括
#pragma注释(lib,“wsock32.lib”)
使用名称空间std;
#定义缓冲区大小1024
作废带有错误的模具(字符*错误消息);
使用错误作废模具(字符*错误消息);
int main(int argc,char*argv[])
{
字符串请求;
字符串响应;
国际代表团;
字符缓冲区[BUFFERSIZE];
serveraddr中的结构sockaddr\u;
int袜子;
WSADATA WSADATA;
char*ipaddress=“210.125.167.240”;
int端口=80;
//http://cwc.ghc.ac.kr/skin/base/board/view_brit2.gif
请求+=“GET/skin/base/board/view\u brit2.gif HTTP/1.0\r\n”;
请求+=“主机:cwc.ghc.ac.kr\r\n”;
请求+=“\r\n”;
//初始化winsock
if(WSAStartup(MAKEWORD(2,0),&wsaData)!=0)
出现错误(“WSAStartup()失败”);
//开放式插座
if((sock=socket(PF_INET,sock_STREAM,IPPROTO_TCP))<0)
出现错误(“套接字()失败”);
//连接
memset(&serveraddr,0,sizeof(serveraddr));
serveraddr.sin_family=AF_INET;
serveraddr.sin\u addr.s\u addr=inet\u addr(ipaddress);
serveraddr.sin_port=htons((无符号短)端口);
if(connect(sock,(struct sockaddr*)&serveraddr,sizeof(serveraddr))<0
出现错误(“connect()失败”);
//发送请求
if(发送(sock,request.c_str(),request.length(),0)!=request.length())
die_带有_wserror(“send()发送的字节数与预期的不同”);
//得到回应
答复=”;
resp_leng=缓冲区大小;
while(resp_leng==BUFFERSIZE)
{
resp_leng=recv(sock,(char*)和buffer,BUFFERSIZE,0);
如果(响应长度>0)
响应+=字符串(缓冲区).substr(0,响应长度);
}
流文件;
myfile.open(“C:\\a\\example.gif”);
//显示响应
cout看起来这个循环就是问题所在:
while (resp_leng == BUFFERSIZE)
{
resp_leng= recv(sock, (char*)&buffer, BUFFERSIZE, 0);
if (resp_leng>0)
response+= string(buffer).substr(0,resp_leng);
}
调用recv()
将从套接字中获得一定数量的字节,这可能比您要求的要少。因此,与读取文件不同,请求BUFFERSIZE
字节可能会返回1到BUFFERSIZE
字节之间的任意位置
相反,循环直到到达套接字的末尾:
while (true)
{
resp_leng= recv(sock, (char*)&buffer, BUFFERSIZE, 0);
if (resp_leng <= 0) {
break;
}
response+= string(buffer,resp_leng);
}
while(true)
{
resp_leng=recv(sock,(char*)和buffer,BUFFERSIZE,0);
如果(resp_leng看起来这个循环就是问题所在:
while (resp_leng == BUFFERSIZE)
{
resp_leng= recv(sock, (char*)&buffer, BUFFERSIZE, 0);
if (resp_leng>0)
response+= string(buffer).substr(0,resp_leng);
}
调用recv()
将从套接字中获得一定数量的字节,这可能比您要求的要少。因此,与读取文件不同,请求BUFFERSIZE
字节可能会返回1到BUFFERSIZE
字节之间的任意位置
相反,循环直到到达套接字的末尾:
while (true)
{
resp_leng= recv(sock, (char*)&buffer, BUFFERSIZE, 0);
if (resp_leng <= 0) {
break;
}
response+= string(buffer,resp_leng);
}
while(true)
{
resp_leng=recv(sock,(char*)和buffer,BUFFERSIZE,0);
如果(resp_leng,您也应该在每个循环中清除接收缓冲区。将其作为循环中的第一行
零内存(缓冲区,sizeof(缓冲区))
当二进制数据留在缓冲区中时,您可能会得到许多意想不到的结果。此外,您还应该在每个循环中清除接收缓冲区。将其作为循环中的第一行
零内存(缓冲区,sizeof(缓冲区))
在缓冲区中保留二进制数据时,您可能会得到许多意想不到的结果。服务器上的图片有多少字节?有趣的是,服务器说内容长度:60
。O很抱歉,它有60个字节,我不得不去查找。服务器上的图片有多少字节?有趣的是,服务器说内容-长度:60
.O抱歉,这是60个字节,我必须去查一下。一直读到recv()
返回得很好,这是真的。我将把我的答案作为如何在循环中读取套接字的示例;解析HTTP头超出了本示例的范围。考虑到这个问题与HTTP处理特别相关,您的答案是错误的处理方法。您真的应该更新它以执行正确的操作。直到recv()
返回得很好,这是真的。我将把我的答案作为如何在循环中读取套接字的示例;解析HTTP头超出了本示例的范围。考虑到这个问题与HTTP处理特别相关,您的答案是错误的处理方式。您确实应该更新它以执行正确的操作。这不是必需的sary和是过度防御编程的一种情况。当recv()
返回值n
(大于零)时,可以确定缓冲区的第一个n
字节已接收到其中的数据。这是我建议使用字符串(缓冲区,响应长度)的原因之一
在我的回答中。这是不必要的,而且是过度防御编程的情况。当recv()
返回值n
(大于零)时,可以确定缓冲区的第一个n
字节已接收到其中的数据。这是我建议使用字符串(缓冲区,响应长度)的原因之一
在我的回答中。