2012-07-10 189 views
2

我寫了一個程序,它向命令行中指定的Web地址發送一個tcp請求並打印響應。當我發送這個請求到www.google.co.uk(或任何網站)時,我沒有得到任何迴應:(C++ HTTP GET請求問題?

有人可以告訴我我做錯了什麼,以及什麼正確的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 GET/1.1這樣的請求。爲什麼在收到答案之前關閉連接? – 2012-07-10 16:15:56

+1

「我什麼都不回來」是什麼意思?你收到0字節,你的程序凍結或突然結束,沒有打印任何東西!? – 2012-07-10 16:16:21

+0

@ViteFalcon:沒關係。如果URL無效,那麼服務器無論如何都會發送正確的HTTP響應(重定向,未找到頁面等) – 2012-07-10 16:17:16

回答

7

一個可能的原因是服務器發送響應之前,希望有更多的數據。

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

ŧ他應該proabably是

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

,這樣你告訴服務器不要期待更多的HTTP報頭(每頭後面是\r\n再額外\r\n添加到結束的請求)。

基本上,您的HTTP請求是不完整的。至少還有一個標題(Host)必須提供。請注意,服務器可能(不正確)接受和不完整的請求。如果您想簡單地開始,請複製瀏覽器發送的請求(例如,打開Web調試器並查看傳出的網絡請求)。

+2

它預計不止於此。一個HTTP 1.1請求也需要包含一個'Host'頭文件,例如:'char * sendbug =「GET /index.html HTTP/1.1 \ r \ n主機:TheServerHostNameHere \ r \ n \ r \ n」;' – 2012-07-10 18:02:27

+0

@RemyLebeau:謝謝。我補充說,答案。 – 2012-07-10 21:20:13