Сокеты загружают слишком мало или слишком много веб-страницы

Почему мой код загружает только половину веб-страницы? Иногда он загружает 4x размер веб-страницы: 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");
}

0

Решение

Редактировать: recv не является нулевым завершением данных для вас — вам нужно записать, сколько данных вы получили, а не просто + = это.


Есть ли в вашем ответе двоичные данные? Если так, то

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

Это не объяснило бы ваши данные 4х.

Другая проблема, которую я вижу, заключается в том, что вы не обнуляете свой буфер после его использования.

IOW: вам нужно написать, сколько данных вы получили, а не просто + = массив.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]