2012-07-10 2 views
2

tcp 요청을 명령 줄에 지정된 웹 주소로 보내고 응답을 인쇄하는 프로그램을 작성했습니다. 내가이 요청을 www.google.co.uk (또는 다른 웹 사이트)로 보내면 나는 아무것도 얻지 못한다. (C++ HTTP GET 요청 문제가 있습니까?

누군가가 내가 옳은 일을하고 있는지, Google에 올바른 GET 요청을 보내야하는지 말해 줄 수 있습니까? 있다. 여기 코드 ... 사전에

#include <WinSock2.h> 
#include <WS2tcpip.h> 
#include <stdio.h> 

#pragma comment(lib, "Ws2_32.lib") 

int main(int argc, char *argv[]){ 

WSADATA wsaData; 
int iResult; 

//Initialize Winsock 
iResult = WSAStartup(MAKEWORD(2,2), &wsaData); 
if(iResult != 0){ 
    printf("WSAStartup failed: %d\n", iResult); 
    return 1; 
} 

struct addrinfo *result = NULL, 
       *ptr = NULL, 
       hints; 

ZeroMemory(&hints, sizeof(hints)); 
hints.ai_family = AF_INET; 
hints.ai_socktype = SOCK_STREAM; 
hints.ai_protocol = IPPROTO_TCP; 

#define DEFAULT_PORT "80" 

//Resolve the server address and port 
iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result); 
if(iResult != 0){ 
    printf("getaddrinfo failed: %d\n", iResult); 
    WSACleanup(); 
    return 1; 
} 

SOCKET ConnectSocket = INVALID_SOCKET; 

//Attempt to connect to the first address returned by 
//the call to getaddrinfo 
ptr = result; 

//Create a SOCKET for connecting to server 
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, 
    ptr->ai_protocol); 

if(ConnectSocket == INVALID_SOCKET){ 
    printf("Error at socket(): %ld\n", WSAGetLastError()); 
    freeaddrinfo(result); 
    WSACleanup(); 
    return 1; 
} 

//Connect to server 
iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen); 
if(iResult == SOCKET_ERROR){ 
    closesocket(ConnectSocket); 
    ConnectSocket = INVALID_SOCKET; 
} 

//Should really try the next address returned by getaddrinfo 
//if the connect call failed 
//But for this simple example we just free the resources 
//returned by getaddrinfo and print an error message 

freeaddrinfo(result); 

if(ConnectSocket == INVALID_SOCKET){ 
    printf("Unable to connect to server!\n"); 
    WSACleanup(); 
    return 1; 
} 

#define DEFAULT_BUFLEN 512 

int recvbuflen = DEFAULT_BUFLEN; 

char *sendbuf = "GET /index.html HTTP/1.1\r\n"; 
char recvbuf[DEFAULT_BUFLEN]; 

//Send an initial buffer 
iResult = send(ConnectSocket, sendbuf, (int)strlen(sendbuf), 0); 
if(iResult == SOCKET_ERROR){ 
    printf("send failed: %d\n", WSAGetLastError()); 
    closesocket(ConnectSocket); 
    WSACleanup(); 
    return 1; 
} 

printf("Bytes Sent: %ld\n", iResult); 

//shutdown the connection for sending since no more data will be sent 
//the client can still use the ConenctSocket for receiving data 
iResult = shutdown(ConnectSocket, SD_SEND); 
if(iResult == SOCKET_ERROR){ 
    printf("shutdown failed: %d\n", WSAGetLastError()); 
    closesocket(ConnectSocket); 
    WSACleanup(); 
    return 1; 
} 

do { 
    iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0); 
    if(iResult > 0){ 
     printf("Bytes received: %d\n", iResult); 
     printf(recvbuf); 
     printf("\n\n"); 
    } else if(iResult == 0){ 
     printf("Connection closed\n"); 
    } else { 
     printf("recv failed: %d\n", WSAGetLastError()); 
    } 
} while(iResult > 0); 

//cleanup 
closesocket(ConnectSocket); 
WSACleanup(); 

return 0; 
} 

감사합니다.

+0

페이지에 요청하지 않고 받으셨습니까? 나는 인덱스 페이지가'index.html' 또는'index.html' 또는'home.html' 등인지 어떻게 알 수 있을까요? 그래서'GET HTTP/1.1'과 같은 요청을 시도 할 것입니다. 그리고 왜 응답을 받기 전에 연결을 닫습니까? –

+1

"나는 아무것도 얻지 못합니다"는 의미는 무엇입니까? 0 바이트를 받으면 프로그램이 멈추거나 아무 것도 인쇄하지 않고 갑작스럽게 끝납니다! –

+0

@ViteFalcon : 그건 중요하지 않습니다. URL이 유효하지 않은 경우 서버는 적절한 HTTP 응답을 보냅니다 (리디렉션, 페이지를 찾을 수 없음 등) –

답변

7

서버가 응답을 보내기 전에 더 많은 데이터를 예상하고 있다는 한 가지 이유입니다.

char *sendbuf = "GET /index.html HTTP/1.1\r\n"; 

T 자신은 proabably 당신이 (각각의 헤더가 다음 추가 \r\n가 요청을 종료하기 위해 추가되는 \r\n 뒤에) 더 HTTP 헤더를 기대하지 않는 서버를 말할 것을

char *sendbuf = "GET /index.html HTTP/1.1\r\n\r\n"; 

어야한다.

기본적으로 HTTP 요청이 완료되지 않았습니다. 최소한 하나 이상의 헤더 (Host)를 제공해야합니다. 서버는 어쨌든 요청을 수락하고 불완전하게 처리 할 수 ​​있습니다. 간단하게 시작하려면 브라우저에서 보낸 요청을 복사하십시오 (예 : 웹 디버거를 열고 나가는 네트워크 요청을 살펴보십시오).

+2

그 이상의 것을 기대하고 있습니다. HTTP 1.1 요청은 'Host'헤더도 포함해야합니다. 예 :'char * sendbug = "GET /index.html HTTP/1.1 \ r \ nHost : TheServerHostName 여기 \ r \ n \ r \ n"; ' –

+0

@ RemyLebeau : 감사합니다. 나는 그 대답에 덧붙였다. –