0
爲什麼我的代碼只下載半個網頁?有時它下載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");
}
啊,這工作。它也修復了4倍數據。 所有我不得不補充的是: Buffer [Val] ='\ 0'; 但我最終改變它像一個你建議的載體。謝謝。 現在唯一的問題是,它有時會爲文件添加額外的符號或數字。我猜想它是以塊的形式下載頁面的,而且可能是塊的長度。不知道如何阻止。 – Brandon
如果你打算解析HTTP響應,你會想要仔細看看這個規範。 –
+1,但沒有必要「清零」整個緩衝區,或者使用2個向量。你可以在循環之前使用'int len = 0;'然後'recvBuffer.resize(len + 50000); int bytesReceived = recv(socket,&recvBuffer [0] + len,recvBuffer.size() - len,0); (注意'data()'僅在C++ 1x中引入;'&recvBuffer [0] + len'保證可以在C++ 03和C++ 1x中工作) 。 –