0

コードがWebページの半分しかダウンロードしないのはなぜですか?時々それはウェブページのサイズの4倍をダウンロードします:S

何が悪いのかわからないので、質問しています。基本的に、私はソケットに接続し、要求を送信し、応答をバッファーに読み取ります。ファイルに保存して画面に印刷してみましたが、不完全なデータや多すぎるデータを印刷して保存してしまいました。バッファオーバーフローかどうか、または何が間違っているのかわかりません。

何か案は?

#define _WIN32_WINNT 0x501

#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <fstream>

using namespace std;

void Get(string WebPage)
{
    WSADATA wsaData;
    string Address;
    struct addrinfo *result;
    struct sockaddr_in  *sockaddr_ipv4;

    char Buffer[50000] = {0};

    string Header = "GET / HTTP/1.1\r\n";
    Header += "Host: " + WebPage + "\r\n";
    Header += "Connection: close\r\n";
    Header += "\r\n";

    if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) return;

    SOCKET Socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

    getaddrinfo(WebPage.c_str(), NULL, NULL, &result);
    if (result->ai_family == AF_INET)
    {
        sockaddr_ipv4 = (struct sockaddr_in *) result->ai_addr;
        Address = inet_ntoa(sockaddr_ipv4->sin_addr);
    }
    freeaddrinfo(result);


    SOCKADDR_IN SockAddr;
    memset(&SockAddr, 0, sizeof(SockAddr));
    SockAddr.sin_port = htons(80);
    SockAddr.sin_family = AF_INET;
    SockAddr.sin_addr.s_addr = inet_addr(Address.c_str());

    if(connect(Socket,(SOCKADDR*)(&SockAddr),sizeof(SockAddr)) == SOCKET_ERROR) return;

    if (send(Socket, Header.c_str(), Header.size(), 0) == SOCKET_ERROR) return;
    shutdown(Socket, SD_SEND);

    std::string Response;

    while(true)
    {
        int Val = recv(Socket, Buffer, sizeof(Buffer), 0);
        if (Val == 0)
            break;
        else if (Val == SOCKET_ERROR)
        {
            cout<<"Error!";
        }
        else
        {
            Response += Buffer;
        }
    }

    closesocket(Socket);
    WSACleanup();

    ofstream File;
    File.open("C:/Saved.html");
    File<<Response;
    File.close();
}

int main()
{
    Get("villavu.com");
}
4

1 に答える 1

3

編集:recvはデータをnullで終了しません-+ =データだけでなく、受信したデータの量を書き込む必要があります。


回答にバイナリデータはありますか?もしそうなら、

Response += Buffer;

最初のヌル文字で停止します。ベクトルを使用して、recvからのデータを次のように格納します。

vector<char> recvBuffer(50000);

int bytesReceived = recv(socket, recvBuffer.data(), recvBuffer.size(), 0);
//error checking
recvBuffer.resize(bytesReceived);

受信したデータを別のベクターに再度保存し、にコピーして戻します。

vector<char> pageContents;

pageContents.insert(pageContents.end(), recvBuffer.begin(), recvBuffer.end());

しかし、それはあなたの4xデータを説明しません。

私が見るもう1つの問題は、使用後にバッファーをゼロにしないことです。

IOW:+ =配列だけでなく、受け取ったデータの量を書き込む必要があります。

于 2012-11-16T03:35:11.430 に答える