2014-09-22 1 views
0

웹 크롤러를 만들려고하는데 로컬 프록시를 통해 웹 사이트에 연결할 수 있기를 원합니다.로컬 프록시를 통해 Google에 GET을 보냅니다. C++. 리눅스. TCP

Google에 GET 메시지를 보내고 HTML 코드를 가져 오려면 로컬 프록시를 통해이 코드를 가져오고 싶다고 가정 해 봅시다. (대학에서 일하고 있고 Google과 같은 외부 사이트에 연결하는 프록시가 있습니다.).

#include <iostream> 
#include <cstring>  // Needed for memset 
#include <sys/socket.h> // Needed for the socket functions 
#include <netdb.h>  // Needed for the socket functions 
#include <cstdlib> 
#include <string> 

using namespace std; 

int main(int argc, char* argv[]) 
{ 
addrinfo host_info;  // The struct that getaddrinfo() fills up with data. 
addrinfo *host_info_list; 
int socketfd; 
char* msg = NULL; 
char* msg2 = NULL; 
int status; 
int len; 

memset(&host_info, 0, sizeof host_info); 

host_info.ai_family = AF_INET;//AF_UNSPEC; 
host_info.ai_socktype = SOCK_STREAM; 

//PROXY IP = proxy.fing.edu.uy ; PORT = 3128 ; //HTTP1.0 proxy 

status = getaddrinfo("proxy.fing.edu.uy", "3128", &host_info, &host_info_list); 

socketfd = socket(host_info_list->ai_family, host_info_list->ai_socktype, 
host_info_list->ai_protocol); 

if (socketfd == -1) std::cout << "ERROR: socket error " << std::endl ; 

std::cout << "Connect()ing..." << std::endl; 

status = connect(socketfd, host_info_list->ai_addr, host_info_list->ai_addrlen); 
if (status == -1) std::cout << "ERROR: connect error" << std::endl ; 

msg = new char[200]; 
strcpy(msg,"CONNECT www.google.com HTTP/1.0\r\n"); 
strcat(msg,"\r\n"); 


ssize_t bytes_sent; 
len = strlen(msg); 
bytes_sent = send(socketfd, msg, len, 0); 

ssize_t bytes_recieved=0; 
std::cout << "Waiting to recieve data..." << std::endl; 

char* incoming_data_buffer = new char[200]; 
bytes_recieved = recv(socketfd, incoming_data_buffer,200, 0); 

if (bytes_recieved == 0) std::cout << "host shut down." << std::endl ; 
if (bytes_recieved == -1)std::cout << "ERROR: receive error!" << std::endl ; 
std::cout << bytes_recieved << " bytes recieved" << std::endl ; 
std::cout << incoming_data_buffer << std::endl; 


msg2 = new char[300]; 
strcpy(msg2,"GET http://www.google.com/ HTTP/1.0\r\n\r\n"); 


std::cout << "Message sent to google: " << msg2 << std::endl; 

len = strlen(msg2); 
bytes_sent = send(socketfd, msg2, len, 0); 

cout << "bytes_sent: " << bytes_sent << endl; 

bytes_recieved=0; 
std::cout << "Waiting to recieve data ..." << std::endl; 

char* incoming_data_buffer2 = new char[1000]; 
bytes_recieved = recv(socketfd, incoming_data_buffer2,1000, 0); 


if (bytes_recieved == 0) std::cout << "host shut down." << std::endl ; 
if (bytes_recieved == -1)std::cout << "ERROR: recieve error!" << std::endl ; 
std::cout << bytes_recieved << " bytes recieved" << std::endl ; 
std::cout << incoming_data_buffer2 << std::endl; 
return 0; 
} 

난 데 문제는 다음과 같이 ... (이하 "CONNECT"에서 버퍼이다) 첫째, incoming_data_buffer 반환입니다 : "HTTP1.0 200 연결

내 코드입니다 설립 ", 좋은, 지금까지 아무런 문제가 없습니다. 다음으로 프록시에 "GET"메시지를 전송하여 예상대로 메시지를 전달합니다 (연결이 설정 됨). 1 분 정도 "recv()"상태로 유휴 상태를 유지 한 다음 메시지를 보냅니다. 0을 반환합니다 (즉, 연결이 닫혀 있음을 의미합니다). 버퍼가 비어 있습니다. 제 문제는 내가 recv()가 0을 반환하는 이유를 전혀 알지 못한다는 것입니다. 아마 연결이 끊어 졌음을 의미하지만, 그 이유는 무엇입니까? 프록시가 연결을 유지하기 위해 내가해야 할 일이 무엇입니까? ("연결이 닫혔다"고 가정하면 문제가됩니다).

미리 감사드립니다.

+0

효과가있었습니다. 난 그냥 연결 메시지를 보내지 않고 GET 메시지를 보냈습니다 그리고 그것은 완벽하게 일했습니다, 대단히 감사합니다 !! –

답변

0

CONNECT 메서드는 HTTP 터널링 기능입니다. 프록시를 지원하는 프록시는 HTTPS 웹 사이트에 연결하는 용도를 제한 할 수 있습니다 (출처 : Wikipedia -- HTTP tunnel). 프록시가 차단할 수있는 CONNECT을 통해 표준 HTTP 서버와의 연결을 설정하려고합니다.

터널을 설정하는 대신 프록시와의 연결을 설정 한 후에 요청을 보냅니다. absoluteURI을 사용하여 GET 대상을 지정 했으므로이 방법이 효과적입니다.

관련 문제