2

コマンドラインで指定されたWebアドレスにtcp要求を送信し、応答を出力するプログラムを作成しました。thisgetリクエストをwww.google.co.uk(または任意のWebサイト)に送信すると、何も返されません:(

誰かが私が間違っていることと、グーグルへの正しい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;
 }

前もって感謝します。

4

1 に答える 1

7

考えられる理由の1つは、サーバーが応答を送信する前により多くのデータを期待していることです。

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

これはおそらく

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

これ以上のHTTPヘッダーを期待しないようにサーバーに指示します(各ヘッダーの後には、リクエストを終了するために\r\n追加\r\nされます)。

基本的に、HTTPリクエストは不完全です。Host提供する必要のあるヘッダー()が少なくとももう1つあります。サーバーはとにかく(誤って)要求を受け入れて不完全にする可能性があることに注意してください。簡単に始めたい場合は、ブラウザから送信されたリクエストをコピーします(たとえば、Webデバッガを開いて、送信ネットワークリクエストを確認します)。

于 2012-07-10T16:19:32.133 に答える