Моя программа Windows Socket не может открыть некоторые URL, которые могут использовать браузеры, такие как FireFox, IE и т. Д. - PullRequest
0 голосов
/ 09 ноября 2011

Я сделал следующую программу для Win32 сокетов для просмотра веб-страниц.Я использую wingw, чтобы избежать зависимости от любой среды выполнения.Чтобы получить ipaddresses, я запускаю URL-адреса, такие как www.google.com, www.yahoo.com, через командную строку и использую эти ip-адреса в своей программе.Порт, конечно, 80.

Я могу получить страницы по умолчанию Google, Yahoo и т. Д., Используя "GET / \ r \ n".Я также могу получать страницы не по умолчанию, даже те, которые находятся внутри каталогов, например http://yasini.com/newsite/index.aspx, используя "GET /newsite/index.aspx".Вывод программы в виде HTML, полученного с веб-сервера, сохраненного на жестком диске.Этот файл позже открывается в Firefox, чтобы посмотреть, как прошла связь.

Я создал тестовую веб-страницу, http://a.domaindlx.com/trysite/hello.asp,, которую я могу открыть в Firefox.Затем я пингую домен a.domaindlx.com и получаю этот ipaddress, 66.36.238.30.Я пытаюсь получить доступ к указанной странице, используя «GET /trysite/hello.asp», но получаю это в ответ: «По этому адресу не настроен веб-сайт. По этому адресу не настроен веб-сайт».

Я знаю, что указанный ответ отправляется веб-сервером, поэтому я смог подключиться к веб-серверу.Проблема в том, что веб-сервер не распознает URL, к которому я пытаюсь получить доступ.Я использовал разные веб-страницы, как htm, так и asp, и ни один из них не доступен.

При попытке открыть веб-сайт с помощью ipaddress непосредственно в браузере я получаю ту же ошибку: «Веб-сайт не настроен ...».

Основная загадка состоит в том, почему эти страницы доступны через браузер, такой как Firefox, а не через мой код, когда мой код, по сути, является браузером, означает открытое соединение с веб-сервером на порту 80.


    #include windows.h
    #include stdio.h

    WSADATA ws;

    int d;
    char aa[1000];
    struct sockaddr_in a;
    SOCKET s;
    int li;

    void abc(char *p)
    {
        FILE *fp = fopen("c:\\data.htm", "a+");
        fprintf(fp, "%s\n", p);
        fclose(fp);
    }

    _stdcall WinMain (HINSTANCE i, HINSTANCE j, char * k, int l)
    {
        d = WSAStartup(0x101, &ws);
        sprintf(aa, "WSASTARTUP = %d", d);
        abc(aa);

        s = socket(AF_INET, SOCK_STREAM, 0);
        sprintf(aa, "SOCKET = %d", s);
        abc(aa);

        a.sin_family = AF_INET;
        a.sin_port = htons(80);
        //a.sin_addr.s_addr = inet_addr("74.125.236.145");
        a.sin_addr.s_addr = inet_addr("66.36.238.30"); //a.domaindlx.com
        //a.sin_addr.s_addr = inet_addr("206.225.85.18"); //www.domaindlx.com
        //a.sin_addr.s_addr = inet_addr("87.248.122.122"); //www.yahoo.com
        //a.sin_addr.s_addr = inet_addr("72.167.153.9"); //www.yasini.com
        d = connect(s, (struct sockaddr *) &a, sizeof(a));

        strcpy(aa, "GET /trysite/hello.asp\r\n");
        strcat(aa, "HTTP 1.0 \r\n\r\n");
        send(s, aa, sizeof(aa), 0);
        li = 1;

        while(li != 0)
        {
            li = recv(s, aa, 1000, 0);
            abc(aa);
        }
    }

Примечание. Пожалуйста, заключите имена файлов заголовков в строку включения в угловые скобки, чтобы код работал.Мне пришлось удалить это, чтобы свойство формат HTML.

Ответы [ 3 ]

1 голос
/ 10 ноября 2011

Проблемный URL-адрес работает на поддомене.Успешные URL не являются.Многие веб-серверы размещают несколько учетных записей на одном и том же физическом IP-адресе, поэтому им необходимо знать, какой конкретный домен / поддомен запрашивается для доступа к правильной учетной записи.Вам необходимо включить в запрос заголовок Host.

Также обратите внимание, что когда вы вызываете send() для отправки запроса, вы отправляете все 1000 байтов буфера aa, что неправильно,Вам нужно отправлять только то, что вы на самом деле заполнили.

Наконец, вы не очень хорошо управляете сокетом в целом.Вам нужна лучшая обработка ошибок.

Попробуйте:

#include <windows.h>
#include <stdio.h>

void abc(char *p, int l = -1)
{
    FILE *fp = fopen("c:\\data.htm", "a+");
    if (fp)
    {
        if (l == -1) l = strlen(p);
        fwrite(p, 1, l, fp);
        fclose(fp);
    }
}

int WINAPI WinMain (HINSTANCE i, HINSTANCE j, char * k, int l)
{
    char aa[1000];

    WSADATA ws;
    int d = WSAStartup(0x101, &ws);
    sprintf(aa, "WSASTARTUP = %d\n", d);
    abc(aa);

    if (d == 0)
    {
        SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
        sprintf(aa, "SOCKET = %d\n", s);
        abc(aa);

        if (s != INVALID_SOCKET)
        {
            char *host = "a.domaindlx.com";
            char *file = "/trysite/hello.asp";

            struct sockaddr_in a;
            memset(&a, 0, sizeof(a));

            a.sin_family = AF_INET;
            a.sin_port = htons(80);

            struct hostent *h = gethostbyname(host);
            if (!h)
            {
                sprintf(aa, "gethostbyname(\"%s\") FAILED\n", host);
                abc(aa);
            }
            else
            {
                sprintf(aa, "gethostbyname(\"%s\") TYPE = %d\n", host, h->h_addrtype);
                abc(aa);

                if (h->h_addrtype == AF_INET)
                {
                    a.sin_addr = * (struct in_addr*) h->h_addr;
                    sprintf(aa, "gethostbyname(\"%s\") IP = %s\n", host, inet_ntoa(a.sin_addr));
                    abc(aa);

                    d = connect(s, (struct sockaddr *) &a, sizeof(a));
                    sprintf(aa, "CONNECT = %d\n", d);
                    abc(aa);

                    if (d == 0)
                    {
                        sprintf(aa,
                            "GET %s HTTP/1.0\r\n"
                            "Host: %s\r\n"
                            "Connection: close\r\n"
                            "\r\n",
                            file, host);

                        char *p = aa;
                        int t = strlen(aa);
                        int li;

                        do
                        {
                            li = send(s, p, t, 0);
                            if (li < 1)
                                break;

                            p += li;
                            t -= li;
                        }
                        while (t > 0);

                        if (t != 0)
                        {
                            abc("SEND FAILED\n");
                        }
                        else
                        {
                            abc("SEND OK\n");

                            do
                            {
                                li = recv(s, aa, sizeof(aa), 0);
                                if (li < 1)
                                    break;

                                abc(aa, li);
                            }
                            while (true);
                        }
                    }
                }
            }

            closesocket(s);
        }

        WSACleanup();
    }

    return 0;
}

Я настоятельно рекомендую вам получить анализатор пакетов, например Wireshark .Затем вы можете точно увидеть, что веб-браузеры (или любое другое приложение сокетов) на самом деле отправляет и получает.Затем вы можете сопоставить это в своем коде по мере необходимости.

1 голос
/ 10 ноября 2011

Есть две проблемы с вашим кодом.Во-первых, пробел должен быть не \ r \ n до HTTP 1.0.Без этого вы отправляете HTTP 0.9.

Вторая проблема заключается в том, что некоторые IP-адреса используются для размещения нескольких сайтов и требуют отправки заголовка узла.

Сайт, который сообщает вам «Нет веб-сайта»настроен по этому адресу "может работать лучше, если добавить заголовок Host :.Ваш запрос к этому сайту должен выглядеть следующим образом:

"GET /trysite/hello.asp HTTP 1.0 \ r \ nHost: a.domaindlx.com \ r \ n \ r \ n"

0 голосов
/ 09 ноября 2011

Вы не следуете протоколу правильно. Вы хотите GET /trysite/hello.asp HTTP/1.0\r\n\r\n См. здесь для полной спецификации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...