Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用http get下载图片只下载图片的一小部分_C++_Http_Winsock - Fatal编程技术网

C++ 使用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

我正在尝试使用http协议GET请求服务器向我发送图片。它会编译并要求提供图片,但服务器只会向我发送一小部分图片

我的代码是:

#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
字节已接收到其中的数据。这是我建议使用
字符串(缓冲区,响应长度)的原因之一
在我的回答中。