Вопрос

I have written a program that sends a tcp request to a web address specified in the command line and prints the response. When I send thisget request to www.google.co.uk (or any website) I get nothing back :(

Could somebody tell me what I'm doing wrong as well as what a correct GET request to google should look like. Here's the code...

#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;
 }

Thanks in advance.

Это было полезно?

Решение

One possible reason is that the server is expecting more data before sending the response.

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

This should proabably be

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

such that you tell the server not to expect more HTTP headers (each header is followed by a \r\n then an extra \r\n is added to end the request).

Basically, your HTTP request is incomplete. There is at least one more header (Host) that must be provided. Note that the server may (incorrectly) accept and incomplete request anyways. If you want to start simple, copy a request sent by your browser (e.g. open the web debugger and look at the outgoing network requests).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top