왜 내 코드는 웹 페이지 절반 만 다운로드합니까? 때로는 웹 페이지 크기의 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 배 데이터도 수정했습니다. 추가 할 내용은 모두 다음과 같습니다. 버퍼 [Val] = '\ 0'; 하지만 당신이 제안한 것처럼 그것을 벡터로 변경했습니다. 고맙습니다. 지금은 파일에 여분의 기호 나 숫자가 추가되는 경우에만 문제가 발생합니다. 나는 그 페이지를 chunk와 아마 chunk 길이로 다운로드한다고 생각한다. 어떻게 그걸 막을 지 모르겠다. – Brandon
HTTP 응답을 구문 분석하려면 사양을 매우 자세히보고 싶을 것입니다. –
+1하지만 완전한 버퍼를 "제로 아웃"하거나 2 개의 벡터를 사용할 필요는 없습니다. 루프 전에 'int len = 0;'을 사용하고,'recvBuffer.resize (len + 50000); int bytesReceived = recv (소켓, & recvBuffer [0] + len, recvBuffer.size() - len, 0); 'recvBuffer [0] + len'는 C++ 03과 C++ 1x에서 모두 작동한다는 것이 보증되어 있습니다.) 또한 len + = bytesReceived; . –