Получение содержимого localhost с помощью winsock - PullRequest
0 голосов
/ 16 апреля 2009

Эй! Я пытаюсь подключиться к своему локальному хосту и странице индекса, которая у меня есть. Но каждый раз, когда я пытаюсь, я просто получаю:

Dados -> HTTP/1.1 400 Bad Request Date: Thu, 16 Apr 2009 15:25:41 GMT Server: Apache/2.2.10 (Win32) PHP/5.2.8 Content-Length: 226 Connection: close Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>400 Bad Request</title> </head><body> <h1>Bad Request</h1> <p>Your browser sent a request that this server could not understand.<br /> </p> </body></html>

Вот код, который у меня есть:

#define WIN32_LEAN_AND_MEAN


#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>

int main()
{
    WSADATA WsaDat;

    if(WSAStartup(MAKEWORD(2,0),&WsaDat)!=0)
    {
        printf("Winsock error - Winsock initialization failed\r\n");
        WSACleanup();
        system("PAUSE");
        return 0;
    }

    SOCKET Socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

    if(Socket==INVALID_SOCKET)
    {
        printf("Winsock error - Socket creation Failed!\r\n");
        WSACleanup();
        system("PAUSE");
        return 0;
    }


    struct hostent *host;
    if((host=gethostbyname("localhost"))==NULL)      
    {
        printf("Failed to resolve hostname.\r\n");
        WSACleanup();
        return 0;
    }

    printf("Resolveu o hostname\r\n");
    SOCKADDR_IN SockAddr;
    SockAddr.sin_port= htons(80);
    SockAddr.sin_family= AF_INET;
    SockAddr.sin_addr.s_addr= *((unsigned long*)host->h_addr);

    if(connect(Socket,(SOCKADDR*)(&SockAddr),sizeof(SockAddr))!=0)
    {
        printf("Failed to establish connection with server\r\n");
        WSACleanup();
        system("PAUSE");
        return 0;
    }

    char get[] = {
                    "GET / HTTP/1.1\n"
                    "From: bla@ble\n"
                    "User-Agent: HTTPTool/1.0\n"
                    "\n"
                };
    send(Socket,get, strlen(get),0);


    printf("Ligou-se\r\n");
    char buffer[1000];
    int nDataLength = recv(Socket,buffer,1000,0);
    printf("Dados -> %s",buffer);


    shutdown(socket,SD_SEND);


    closesocket(socket);

    WSACleanup();



    return 0;
}

Чего-то не хватает? Я следую учебному пособию, и это в основном код, который у них есть.

Спасибо

Ответы [ 4 ]

1 голос
/ 16 апреля 2009

HTTP 1.1 требуется заголовок Host: localhost - либо добавьте его, либо используйте HTTP 1.0

Кроме того, заголовки разделены \r\n, а не просто \n.

0 голосов
/ 17 июня 2009

Вы также можете попробовать использовать WinInet для нужд Http на стороне клиента, а не только для сокетов.

Множество людей подключаются к веб-службам через прокси-серверы, то есть их собственный компьютер не может получить доступ к сети, но может подключиться к ближайшему компьютеру (прокси-серверу), который будет пересылать запрос. Ваш код сокета не обрабатывает прокси, но WinInet API сделает это автоматически.

[Как старомодный сетевой специалист, я ненавижу эти устройства - они по сути плохо внедрили маршрутизаторы]

Точно так же вы можете переключить свой сервер на https: когда-нибудь; у вас будет немало времени, чтобы обновить код сокета, чтобы справиться с этим, но опять же, WinInet сделает это за вас.

[Примечание: я работаю в Microsoft]

0 голосов
/ 14 мая 2009

Возможно, будет проще попробовать использовать HTTP / 1.0, для которого вам не нужно указывать дополнительные значения:

char get [] = { "GET / HTTP / 1.0 \ r \ n" };

Должен работать везде ...

0 голосов
/ 17 апреля 2009

Как сказал Роборг, ваша строка get должна быть:

    char get[] = {
                "GET / HTTP/1.1\r\n"
                "Host: localhost\r\n"
                "From: bla@ble\r\n"
                "User-Agent: HTTPTool/1.0\r\n"
                "\r\n"
            };

Если вы подключаетесь к другим сайтам, кроме localhost, поле 'host' должно быть обновлено (обычно работает имя хоста, IP-адрес или www).

...