c++ - 用http get下载一张图片,只下载了一小部分

标签 c++ http winsock

我正在尝试使用 http 协议(protocol) 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
*/

怎么了,为什么不下载完整图片?

最佳答案

看起来这个循环是问题所在:

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);
}

请注意,我还在循环的最后一行更改了对 string() 构造函数的调用(您的可以工作,但会比必要的做更多的工作)。

关于c++ - 用http get下载一张图片,只下载了一小部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9389183/

相关文章:

c++ - 在 X11 上设置 OpenGL

php - GET 与 POST 最佳实践

C++生成随机数

django - 是否应该捕获来自 HTTP 参数问题的不可恢复异常?

python - 通过 Python 的单个连接进行多个请求

windows - 如何确定 Windows Sockets 发送缓冲区是否为空?

c++ - 为什么 Windows 不允许在模拟另一个用户时启动 WinSock

c++ - 由于错误代码10093,C++程序无法连接到服务器

c++ - 这个循环有什么问题吗?

c++ - rapidjson writer 生成额外的大括号